2

my problem is as follows: I'm writing a script whose purpose is to run a certain scripts on different servers in parallel. I.e., I want to log into a remote server, enter the password (this is not negotiable because boss), starts the script, close the connection while the script is still running, connect to the next server and do the whole dance again. How do I do it?

4

3 回答 3

2

登录后,您可以使用 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
于 2014-01-09T14:43:09.867 回答
0

假设 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
于 2014-01-09T19:38:02.733 回答
0

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
}
于 2014-01-09T15:27:48.690 回答