GNU bash,版本 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
发生这种情况是因为您使用了ssh -t
.该-t
选项在远程端分配一个 tty。
当远程命令工作时,远程 tty 很可能处于回显输入的模式。就像当您在本地运行cat
并键入它时,您会看到 tty (而不是 )回显的输入,cat
并且只有在Enteror Ctrl+d cat
读取它并打印为输出时。
在您的情况下,远程 tty 会回显本地ssh
从其标准输入读取的内容。然后将其result=$(ssh …)
与远程命令的“真实”输出一起捕获。
如果您不需要远程 tty,请不要传递-t
到ssh
。
如果您确实需要远程 tty,请传递-t
但不要ssh
从本地 stdin: 读取</dev/null ssh -t …
。请注意,您根本无法输入远程命令。
如果您确实需要远程 tty 并且确实需要将某些内容从本地 stdin 传递(键入)到远程命令,请传递-t
,不要将 stdin 重定向到/dev/null
,而是告诉远程 tty 关闭其回显。您可以通过添加stty -echo;
到$cmds_services
.您不需要stty echo
在最后打开 echo(使用 ),因为远程 tty 无论如何都会被破坏。请注意,中的任何命令$cmds_services
都可能重新配置 tty;根据命令,您可能能够也可能无法阻止这种情况。
在一个非常苛刻的情况下,你可能会发现我的这个问题很有用:ssh
具有单独的 stdin、stdout、stderr 和 tty。即使您不需要它,您也可以从它、我的回答以及其中的链接中获得一些见解。