GNUバッシュ、バージョン4.3.27
出力をファイルに書き込むスクリプトに奇妙な問題があります。サーバーリストに接続し、一部のサービスのステータス/サブステータスを記録するようにsshをスクリプトします。次に、結果を配列に保存します。
しかし、コンソールウィンドウの実行中に何かを入力すると、入力が配列に保存されますが、$result_arr
その理由はわかりません。
#!/bin/bash
check_services()
{
server_number="$1"
local result
local result_arr
local error_flag="OK"
#Get service status
result=$(ssh server.$host -t "$cmds_services")
#trim carriage returns if present
result=$(echo "$result" | tr -d '\r')
#split result into array by line
readarray -t result_arr <<<"$result"
echo "$server_number,${result_arr[0]},${result_arr[1]},${result_arr[2]},${result_arr[3]},${result_arr[4]},${result_arr[5]},${result_arr[6]},${result_arr[7]}" >> "$OUTFILE"
}
main()
{
for server in $(cat /home/data/serverlist)
do
clear -x
echo "Gathering Data...Server $server"
check_services "$server"
done
}
スクリプトの実行中に「a」をスパムに送信して入力すると、$OUTFILE
次のようになります。
1234,active,mounted,active,mounted,a,,a,a
変える
1234,active,mounted,active,mounted,active,mounted,active,mounted
答え1
これは、リモート側でttyを割り当てるために 。オプションを使用したために発生しますssh -t
。-t
リモートコマンドが動作しているとき、リモートttyはエコーモードである可能性が高いです。ローカルで実行しcat
て入力するのと同じように、tty(not)でエコーされた入力を見ることができますcat
。EnterCtrld cat
あなたの場合、リモートttyはssh
ローカルが標準入力から読み取った内容をエコーします。その後、result=$(ssh …)
リモートコマンドの「実際の」出力とともにキャプチャされます。
リモートttyが不要な場合-t
は渡さないでくださいssh
。
リモートttyが本当に必要な場合は渡しますが、ローカルのstdinでは読ま-t
ないでください。リモートコマンドはまったく入力できません。ssh
</dev/null ssh -t …
リモートttyが本当に必要で、ローカルstdinからリモートコマンドに何かを渡す(入力)する必要がある場合は、stdinにリダイレクトせずにリモートttyにエコーをオフにするように指示してください-t
。に追加すると、これを行うことができます。とにかくリモートttyが削除されるため、最後にechoをオンにする必要はありません。のすべてのコマンドは、コマンドに応じてttyを再構成することができ、これを防ぐこともできない場合もあります。/dev/null
stty -echo;
$cmds_services
stty echo
$cmds_services
非常に厳しい場合は、次の質問が役に立ちます。ssh
独立したstdin、stdout、stderr、ttyがあります。。必ずしも必要なくても、その内容と私の答え、その中にあるリンクからインサイトを得ることができます。