【问题标题】:Executing remote bash script over ssh in a loop在循环中通过 ssh 执行远程 bash 脚本
【发布时间】: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&gt;$timetime 的标准错误捕获到一个文件中,2&gt;/dev/null 在出错时保持安静,&lt;/dev/null 防止ssh 窃取stdin,因此它可以安全地循环运行。

问题是,当用户使用ctrl+c 终止脚本时,脚本的副本仍应在远程主机上正常终止(即文件被重命名为初始名称),但事实并非如此。在没有循环的情况下做同样的事情可以正常工作 - 用户终止脚本,远程复制仍在运行并正常结束,用户只是看不到输出,这很好。我的理论是这个问题与ssh 处于循环和&lt;/dev/null 阻止它窃取stdin 有关,但我想不出绕过这个的方法。非常感谢任何建议。

【问题讨论】:

  • nohup 下远程运行脚本会改变行为吗?

标签: bash loops ssh stdin


【解决方案1】:

user2303197 的建议非常有意义 - 使远程脚本不受挂断信号的影响,但不幸的是,它不会影响脚本的行为。但是这个建议启发了我做完全相反的事情——nohup ssh 调用,像这样:

result=$((time nohup ssh ${!server} "$(basename $0) argument" & 2>/dev/null </dev/null) 2>$time)

它使 ssh 对ctrl+c 免疫,但它一完成就打破了它正在运行的循环,而这正是我需要它做的。

编辑: 经过一周的测试,事实证明这个脚本没有按我的意愿执行。当与远程主机的连接断开时,远程脚本不会正常结束。有什么建议可以解决这个问题吗?

【讨论】:

    猜你喜欢
    • 2011-05-09
    • 2018-09-15
    • 2012-01-12
    • 2017-08-02
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    相关资源
    最近更新 更多