PowerShellでscp(ssh)

Windows11環境のPowerShellからSSHの公開鍵認証でscpによるファイルコピーを実現したときの備忘録。

  1. バージョン確認
PS C:\Users\foo> ssh -V
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
  1. キー作成

パスフレーズは入力しないで鍵を生成。

PS C:\Users\foo> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\foo/.ssh/id_rsa):
Created directory 'C:\Users\foo/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\foo/.ssh/id_rsa.
Your public key has been saved in C:\Users\foo/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:........................................................
The key's randomart image is:
+---[RSA 3072]----+
|   ...........   |
|   ...........   |
|   ...........   |
|   ...........   |
+----[SHA256]-----+
PS C:\Users\foo>
  1. 公開鍵をサーバに追加

sloginってコマンドはPowerShellにはないみたい。 ssh -lでログインするが、ユーザ名@ホスト名って書き方できないんだっけ?

PS C:\Users\foo> ssh -l ユーザ名 ホスト名
ユーザ名@ホスト名's password: パスワードを入力

サーバ側にログイン後、.ssh/authorized_keysにキー作成で作成したid_rsa.pubの内容を追加。

$ cd .ssh
$ chmod 600 authorized_keys
$ cat id_rsa.pub >> authorized_keys
$ chmod 400 authorized_keys

このあと、念のためPowerShellからssh -l でパスワードなしでログインできるか確認しておく。

  1. ファイルコピー

scpを使ってパスワードなしでWindows11ローカルのファイルをサーバ側ホームディレクトリにコピー。 destinationの最後の":"が大事(これがないとローカルの「ユーザ名@ホスト名」というファイル名にコピーするだけ)。":"の後にホームディレクトリの相対パスを指定すればそのパスにコピー。

PS C:\Users\foo> scp コピーしたいファイル名 ユーザ名@ホスト名:
コピーしたいファイル名                              100%   23MB 890.7KB/s   00:25

参考サイト

https://click.jp/knowledge/1476/

https://monolithon.net/archives/2019/07/550

PL/SQLのCASE文のELSEって省略できない

PL/SQLを実行すると、

エラーコード: ORA-06592
詳細: CASE文の実行中にCASEが見つかりません

となってしまった場合は、 OraclePL/SQLに記載したCASE WHEN ... END CASEでELSEを省略している可能性あり。

https://www.366service.com/jp/qa/82975fbbfe8c0f01d07862451289b7c4

oracle公式のマニュアル (https://docs.oracle.com/cd/E15817_01/appdev.111/e05670/controlstructures.htm)[4 PL/SQLの制御構造の使用] の「例4-6 単純なCASE文」を見ると、

SQL> DECLARE
  2    grade CHAR(1);
  3  BEGIN
  4    grade := 'B';
  5
  6    CASE grade
  7      WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
  8      WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
  9      WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
 10      WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
 11      WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
 12      ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
 13    END CASE;
 14  END;
 15  /
Very Good

PL/SQL procedure successfully completed.

SQL>

とあり、

選択子の後に1つ以上のWHEN句があり、各句が順番にチェックされます。

選択子の値によって、どの句が実行されるかが決定されます。

選択子の値がWHEN句の式の値と等しければ、そのWHEN句が実行されます。

たとえば、最後の例では、gradeが'C'であれば、'Good'が出力されます。

実行が失敗することはなく、WHEN句が1つでも実行されると、制御が次の文に渡されます。

ELSE句の機能は、IF文のELSE句に似ています。

前述の例では、学年がWHEN句のオプションの1つでなければ、ELSE句が選択され、'No such grade'という句が出力されます。

ELSE句はオプションです。

ただし、ELSE句を省略すると、PL/SQLでは次の暗黙的なELSE句が追加されます。

ELSE RAISE CASE_NOT_FOUND;

という説明がある。 省略すると「CASEがないとエラーを上げます」ってこと。 つまり、PL/SQLのELSEは省略できないってことだよね。紛らわしい。

OracleのSQLファイルに引数を渡す場合のドット(.)

-- test.sql
-- スキーマ名.テーブル名でスキーマを引数から取得
SELECT COUNT(*) FROM &1..MYTBL;
EXIT;
C:\> sqlplus FOO/PASS@SERVICENAME @test.sql SCHEMATEST

ドットは区切り文字ということなので&1.が引数に展開されて SCHEMATEST.MYTBLになる。

SET DEFINE - オラクル・Oracle SQL*Plus リファレンス置換変数の使用方法によれば、

置換変数は単独で使用する場合には &変数名 として使用する。 &変数名xxxyyyy などと文字列が続く場合には 変数名xxxyyyy が変数名として解釈される。 そのため &変数名.xxxyyy のように後続文字列の間にドット(.) を設置することで変数名と文字列を区切りって変数名だけを認識させる。

置換変数の直後に文字を追加する場合は、変数と文字の区切りにピリオドを使用します。次に例を示します。

と記載あり。

Oracleのv$sessionのSQLを参照してみたい

v$sessionのstatusがINACTIVEの場合は大抵sql_idがなくってsqlがわかんねって思っていたら 以下のサイトを参考にしたところわかりそうだったのでメモ。

https://qiita.com/e99h2121/items/5032d081b11fba684420

ここの【2】を参考にしてみた。

SELECT a.sid SID, a.serial# SERIAL, a.terminal TERMINAL
     , floor(a.last_call_et/3600)||':'|| floor(mod (a.last_call_et,3600)/60)||':'|| mod(mod(a.last_call_et,3600),60) "TIME"
     , SUBSTRB(a.program,1,10) PROGRAM, a.status, a.osuser, a.logon_time, b.sql_text SQLTEXT 
  FROM v$session a, v$sqltext b
 WHERE a.sql_address = b.address
   AND a.sql_hash_value = b.hash_value
   AND a.username is not null
   AND a.schemaname = 'スキーマ名'
   AND a.logon_time between '2022/02/01 00:00:00' and '2022/02/02 00:00:00'
 ORDER BY a.sid,b.piece
;