【发布时间】:2014-08-29 00:20:04
【问题描述】:
我遇到的问题非常具体:
我有一个脚本,它无限期地遍历服务器列表,并在每个服务器上执行自身的副本(带有特定的参数集)。应该捕获远程脚本stdout,以及执行它所花费的时间。这是一个非常简化的示例:
export TIMEFORMAT="%0E seconds"
server1=localhost
index=1
if [ "$1" != "" ]
then
cd /home
mv -n test _test &>/dev/null
sleep 10
echo $1
mv -n _test test &>/dev/null
else
i=0
while [ $i -lt $index ]
do
((i++))
server="server$i"
time=/tmp/time
echo "${!server} is doing stuff..."
result=$((time ssh ${!server} "$(basename $0) argument" 2>/dev/null </dev/null) 2>$time)
echo "Done in $(<$time), the result is $result"
rm $time
done
fi
因此,如果脚本接收到参数,它会在本地执行(例如,重命名文件并且 10 秒内不执行任何操作);否则,它将遍历服务器列表(例如,列表中只有一个服务器)并在远程主机上调用自身。 2>$time 将time 的标准错误捕获到一个文件中,2>/dev/null 在出错时保持安静,</dev/null 防止ssh 窃取stdin,因此它可以安全地循环运行。
问题是,当用户使用ctrl+c 终止脚本时,脚本的副本仍应在远程主机上正常终止(即文件被重命名为初始名称),但事实并非如此。在没有循环的情况下做同样的事情可以正常工作 - 用户终止脚本,远程复制仍在运行并正常结束,用户只是看不到输出,这很好。我的理论是这个问题与ssh 处于循环和</dev/null 阻止它窃取stdin 有关,但我想不出绕过这个的方法。非常感谢任何建议。
【问题讨论】:
-
在
nohup下远程运行脚本会改变行为吗?