【发布时间】:2025-05-01 11:20:02
【问题描述】:
我的问题如下:我正在编写一个脚本,其目的是在不同的服务器上并行运行某些脚本。即,我想登录远程服务器,输入密码(这是不可协商的,因为老板),启动脚本,在脚本仍在运行时关闭连接,连接到下一个服务器并再次完成整个舞蹈。我该怎么做?
【问题讨论】:
标签: bash ssh parallel-processing remote-execution
我的问题如下:我正在编写一个脚本,其目的是在不同的服务器上并行运行某些脚本。即,我想登录远程服务器,输入密码(这是不可协商的,因为老板),启动脚本,在脚本仍在运行时关闭连接,连接到下一个服务器并再次完成整个舞蹈。我该怎么做?
【问题讨论】:
标签: bash ssh parallel-processing remote-execution
假设 bash 是所有远程机器上的目标 shell,你可以为一台机器做:
ssh user@host /path/to/script '&>/dev/null' '</dev/null' '&' disown
对于多台机器,您可以编写如下脚本:
hosts='user1@host1 user2@host2'
for host in $hosts
do
ssh $host /path/to/script '&>/dev/null' '</dev/null' '&' disown
done
这应该只是让您输入密码。
或者,如果您可以为多台机器使用相同的密码,我建议您查看ClusterSSH。有了这个,您可以同时登录到多台机器,并在单个窗口中或在每个 xterm 窗口中单独键入要发送给所有机器的命令。这样可以避免您重复输入相同的密码。登录后,您可以像上面那样运行命令(不带ssh user@host 部分)并退出。
这里有几个额外的想法。首先,完全放弃脚本输出可能不是一个好主意,因为如果出现问题,您永远不会知道会发生什么。您可以将其放入一个文件中,以便稍后通过将'&>/dev/null' 替换为'&>filename' 来查看。另一种方法是让远程机器通过电子邮件将其发送给您(前提是它已正确设置为执行此操作):
host=user@host
ssh $host \(/path/to/script '2>&1' \| mail -s "$host output" me@me.com\) \
'&>/dev/null' '</dev/null' '&' disown
其次,如果脚本在本地主机上,您可以将其复制并在一个命令中执行。假设一个 shell 脚本,如果不只是用正确的解释器替换 sh)
</path/to/script ssh user@host \
cat \>script \; sh ./script '&>/dev/null' '</dev/null' '&' disown
【讨论】:
ssh $host '/path/to/script' 'argument' '&>/dev/null' '</dev/null' '&' disown.
expect 可以很容易地自动执行此操作:
#!/usr/bin/expect -f
set hosts {your list of hosts goes here ...}
foreach host $hosts {
spawn ssh -t user@$host screen ./script.sh
expect "assword:"
send -- "secret\r"
sleep 1
send -- "d"
expect eof
}
【讨论】:
登录后,您可以使用 screen 实用程序启动新的终端会话,然后再从中分离,例如:
[user@local]$ ssh machine
[user@machine]$ screen -S my_session
# you are now switched to new terminal session named "my_session"
# now you can start long operation, that you want to keep in background
[user@machine]$ yes
# press "Ctrl-a d" to detach, you will go back to original session
[detached from 11271.my_session]
# now you can leave ssh (your session with "yes" running will be kept in background)
# to list existing screen sessions run:
[user@machine]$ screen -list
There is a screen on:
11271.my_session (Detached)
1 Socket in /var/run/screen/S-user.
# to re-attach use -r
[user@machine]$ screen -r my_session
# you will be back to session with "yes" still running (press Ctrl-C to stop it)
一旦您了解屏幕的工作原理,您就可以尝试编写脚本;这就是您在运行 my_command 的分离状态下启动屏幕会话的方式:
$ screen -d -m my_command
【讨论】:
ssh user@host screen -d -m"./script.sh"。我得到屏幕使用输出。选项 -m 显示为“忽略 $STY 变量,创建一个新的屏幕会话。”
script.sh 在主机上并且可执行。我在this thread找到了解决方案:
ssh -n -f -p$SSH_PORT test@localhost "bash -c 'nohup ./test.sh 2>&1 > test.log &'"