我有一个很长的远程主机列表,我想在所有的主机上运行一个shell命令。 这个命令需要很长时间,所以我想在内部运行这个命令。screen
在远程机上我希望在命令退出后,远程的终端输出能被保留。 有一个 "标签 "应该作为参数提供给每个命令。 我试着用 parallel
类似这样。
$ cat servers.txt
[email protected]/tag1
[email protected]/tag2
# ...
$ cat run.sh
grep -v '^#' servers.txt |
parallel ssh -tt '{//}' \
'tag={/}; exec screen slow_command --option1 --option2 $tag other args'
这行不通:所有的远程进程都被启动了,但它们并没有被分离出来(所以ssh会话仍然是实时的,而我没有得到我的本地shell),而且每个命令完成后,它的屏幕立即退出,输出也丢失了。
如何修复这个脚本? 注意:如果用 tmux
或其他的集结程序 parallel
,我很高兴听到解释如何这样做的答案。
就像这样。
grep -v '^#' servers.txt |
parallel -q --colsep / ssh {1} "screen -d -m bash -c 'echo do stuff \"{2}\";sleep 1000000'"
最后... sleep
确保屏幕不死。你将有1000000秒的时间来附加到它并杀死它。
有一个可怕的很多引用那里 - 特别是当 do stuff
是复杂的。
可能更容易做一个函数来计算 tag
的远程机器上。你需要GNU Parallel 20200522来实现。
env_parallel --session
f() {
sshlogin="$1"
# TODO given $sshlogin compute $tag (e.g. a table lookup)
do_stuff() {
echo "do stuff $tag"
sleep 1000000
}
export -f do_stuff
screen -d -m bash -c do_stuff "$@"
}
env_parallel --nonall --slf servers_without_tag f '$PARALLEL_SSHLOGIN'
env_parallel --endsession