Bash
如何使用 bash“正確”讀取遠端 sshd 伺服器版本
我正在嘗試在不安裝額外工具的情況下使用 bash 讀取遠端 SSHD 伺服器版本:
$ cat < /dev/tcp/x.y.z.t/22 SSH-2.0-OpenSSH_7.2 FreeBSD-20160310 ^C
需要 CTRL+C,所以我嘗試只讀取一行,但輸出中發生了一些奇怪的事情:
$ 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
如何防止 bash
read
內置讀取尾隨\r
字元?
該
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
對於 Internet 協議,該序列通常是強制性的,並且與典型的 Unix\n
換行符序列不同,但這是一個不同的問題……但這就是那個討厭\r
的問題存在的原因。)