标题说明了问题。我必须同时在多个系统上运行终端命令。例如,我必须sudo apt install -y firefox
在同一网络上的每台计算机上运行。假设我有所有计算机的 IP 地址列表,并且每台计算机的用户名和密码都相同。所有系统都运行Ubuntu 20.04 LTS或者16.04 LTS。这样做的目的是节省在 100 多台计算机上手动运行命令的时间。
简单来说,就是一台计算机充当管理员的角色,在其他计算机上运行命令。
答案1
注意:问题最初询问的是同时在多台机器上运行命令 - 因此我的第一个解决方案是使用 Tmux。这可能不适合同时运行 100 台机器。
使用 Tmux(完全或部分手动)或编写脚本(全自动)。
建议熟悉 Tmux 命令和快捷方式 - 最好通过创建自己的配置。但这里介绍如何使用默认配置(手动)执行此操作。
开始新会话:
tmux new -s mysession
将窗口分成 X 个窗格:
- Ctrl+ b,然后%(水平分割)
- Ctrl+ b,然后"(垂直分割)
Ctrl使用+在窗格中导航b,然后Arrow keys
在每个窗格上,通过 SSH 进入不同的机器:
ssh user@host
进入命令模式:
- Ctrl+ b,然后:。然后输入:(
setw synchronize-panes
现在每个命令都会发送到所有窗格)
输入您想要运行的命令:
sudo apt install -y firefox
现在它将通过每台机器上的 SSH 运行。
您还可以编写一个使用 Tmux 连接到您的 IP 列表的脚本。然后您可以在同步模式下手动运行命令,也可以通过脚本运行。
如果你有 10 台机器,我会使用 Tmux。如果你有 100 台机器,可以考虑用脚本完全自动化。
参考:Tmux 备忘单。
答案2
这是一个可能的解决方案,在答案末尾的参考资料中提供了更详细的主题。下面介绍的脚本的工作原理如下。
1.创建可执行脚本文件,名为populate-ssh-cmd
。将其放入用户~/bin
(或/usr/local/bin
)目录中,以便作为 shell 命令访问。
cat ~/bin/populate-ssh-cmd
#!/bin/bash
# Get the user's input as command
[[ -z ${@} ]] && exit || CMD_EXEC="${@}"
# Get the hosts from ~/.ssh/config whose names are prefixed by `lan-`
HOSTS=$(grep -Po 'Host\s\Klan-.*' "$HOME/.ssh/config")
# Test weather the input command uses sudo
if [[ $CMD_EXEC =~ ^sudo ]]
then
# Ask for password
read -sp '[sudo] password for remote_admin: ' password; echo
# Rewrite the command
CMD_EXEC=$(sed "s/^sudo/echo '$password' | sudo -S/" <<< "$CMD_EXEC")
fi
# loop over the hosts and execute the SSH command, remove `-a` to override the logs
while IFS= read -r host
do
echo -e '\n\033[1;33m'"HOST: ${host}"'\033[0m'
ssh -n "$host" "$CMD_EXEC 2>&1" | tee -a "/tmp/$(basename "${0}").${host}.log"
done <<< "$HOSTS"
chmod +x ~/bin/populate-ssh-cmd
笔记:
2>&1
将远程 STDERR 重定向到 STDOUT,即通过管道传输到tee
命令,该命令将显示它并将其写入每个远程主机的单独日志文件。要列出日志文件,请键入ls -la /tmp/populate-ssh-cmd.sh.lan-*
。该脚本只会询问
sudo
一次远程管理员的密码,因此所有远程实例的管理员必须具有相同的密码。
2.在文件中添加 LAN 主机的条目~/.ssh/config
,并在其名称前加上前缀lan-
。因此~/.ssh/config
文件应如下所示。
Host lan-1-some-additional-info
HostName 192.168.1.101
IdentityFile ~/.ssh/lan-hosts/id_rsa
User remoteUser
Host lan-2-some-additional-info
HostName 192.168.1.102
IdentityFile ~/.ssh/lan-hosts/id_rsa
User remoteUser
Host lan-3-some-additional-info
HostName 192.168.1.103
IdentityFile ~/.ssh/lan-hosts/id_rsa
User remoteUser
3.populate-ssh-cmd
按如下方式使用脚本。
populate-ssh-cmd sudo apt install -y firefox
上述脚本使用基于 SSH 密钥的身份验证,这种身份验证比使用密码更容易实现,也更安全。如果您想使用基于密码的身份验证,您可以sshpass -p 'footbar'
按照以下参考资料中的描述进行实现:
答案3
我做了一些类似的事情,在设置后相当容易。我在主 PC 上为每台计算机创建别名,这样我只需为 10 台计算机中的每一台输入 3 个字母,即可 ssh 进入每台计算机并为每台计算机创建一个选项卡。还有更新和升级的别名,我可以在几分钟内完成所有 10 个。例如,一个选项卡 su1,下一个选项卡 su2 等,然后在每个选项卡中输入 ud for apt-get update -y,然后在每个选项卡中输入 dug for 和 apt-get dist-upgrade -y。因此,通过快速切换到每个终端选项卡,我几乎可以像一个一样快速地完成 10 个。我也用这种方式执行其他一些命令。