追加のツールをインストールせずにbashを使用してリモートSSHDサーバーのバージョンを読み取ろうとします。
$ cat < /dev/tcp/x.y.z.t/22
SSH-2.0-OpenSSH_7.2 FreeBSD-20160310
^C
Ctrl + Cが必要なので、1行だけ読み取ろうとしましたが、出力で奇妙なことが発生しました。
$ read version < /dev/tcp/x.y.z.t/22
$ echo "=> version = $version, DONE."
, DONE.ion = SSH-2.0-OpenSSH_7.2 FreeBSD-20160310
\r
変数値の末尾に文字があることがわかりましたversion
。
$ printf "$version" | od -ct x1z
0000000 S S H - 2 . 0 - O p e n S S H _
53 53 48 2d 32 2e 30 2d 4f 70 65 6e 53 53 48 5f >SSH-2.0-OpenSSH_<
0000020 7 . 2 F r e e B S D - 2 0 1 6
37 2e 32 20 46 72 65 65 42 53 44 2d 32 30 31 36 >7.2 FreeBSD-2016<
0000040 0 3 1 0 \r
30 33 31 30 0d >0310.<
0000045
read
bash組み込み機能が末尾の文字を読み取らないようにする方法は\r
?
答え1
このIFS
変数は(ローカルで!)修正されて\r
。
function read-ssh-version {
local IFS=$'\r\n'
read version < /dev/tcp/"$1"/"$2"
echo "$version"
}
IFS
関数が機能し、グローバル変数が変更されていないことを確認するためのいくつかの最小限の一時的なテスト:
bash-5.1$ read-ssh-version 127.0.0.1 22 | od -c
0000000 S S H - 2 . 0 - O p e n S S H _
0000020 9 . 0 \n
0000024
bash-5.1$ echo -n "$IFS" | od -c
0000000 \t \n
0000003
(この\r\n
シーケンスは通常インターネットプロトコルに必須であり、一般的なUnix改行シーケンスとは異なりますが、それは別\n
の質問です...しかし、それがまさにその不快なことが\r
存在する理由です。)