如何在 运行 多个命令 Linux 的同时 运行 并行 ssh 连接
How to run ssh connection in parallel while running multiple commands Linux
我试图了解在远程主机上 运行 以 parallel
方式使用 ssh
执行多个命令的最佳方法,并在挤压警告时在屏幕上显示输出,屏幕上的错误。
此 post 主要与 where KamilCuk 联系 POST 用一些漂亮的技巧回答了 POST 但是我还有一些未解决的问题。
下面的代码适用于给定的命令,但是我的系统中很少有人真的很旧并且不理解 nproc
命令来获取系统上的处理器数量因此我需要使用 grep -c processor /proc/cpuinfo
如果我在 tmp=$(ssh "$server" bash -c 'grep -c "^processor" /proc/cpuinfo; free -g')
.
这样的当前解决方案中这样做,这是行不通的
也会考虑合并条件,例如如果 nproc
存在,则使用文件 /proc/cpuinfo
来计算 CPU,这只是一件与许多其他事情相似的事情。
因此,如果您有不同的命令子集需要从 commands
和 files
.
获取值,那么如果有更多方法可以做到这一点,我很期待
#!/bin/bash
read -rsp $'Please Enter password below: ' SSHPASS
export SSHPASS
work() {
server=
# ONE connection
tmp=$(ssh "$server" bash -c 'nproc; free -g')
# parsing later
cpu_info=$(<<<"$tmp" awk 'NR==1')
mem_info=$(<<<"$tmp" awk '/Mem:/{printf }')
swap_info=$(<<<"$tmp" awk '/Swap:/{printf }')
# outputting
printf "%-40s %5s %5s %5s\n" "$server" "$cpu_info" "$mem_info" "$swap_info"
}
export -f work
< /home/user1/mem xargs -P0 -n1 -d'\n' bash -c 'work "$@"' _
我试过下面的想法是 borrowed from 但它只打印 SEREVR
名称,没有其他内容:
#!/bin/bash
read -rsp $'Please Enter password below: ' SSHPASS
export SSHPASS
for SERVER in '$(cat /home/user1/mem)'
do
sshpass -e ssh -q -t -oStrictHostKeyChecking=no $SERVER << EOF
cpu_info=$(grep processor /proc/cpuinfo | awk 'NF==3{count++} END {printf count}')
mem_info=$(free -g | awk /Mem:/{printf' '})
swap_info=$(free -g | awk /Swap:/{printf' '})
printf "%-40s %5s %5s %5s\n" "$server" "$cpu_info" "$mem_info" "$swap_info"
EOF
done | tee 2>/dev/null
我可能有很多错误,请原谅我只是想学习。
编辑注:
我知道会有一个明确的问题,为什么不使用 ssh keys
或 already existed tooling
,比如 ansible,salt 等,原因只是,由于公司安全政策,我们不能使用任何他们没有办法重新发明轮子,但是我们在正常环境中大量使用 Ansible 和其他工具。
首先,这个循环不起作用:
for SERVER in '$(cat /home/user1/mem)'
do
...
done
因为 '',删除 '' 或最好先读取 var 或数组中的主机列表:
var=$(cat /home/user1/mem)
arr=($(cat /home/user1/mem))
并循环这个 var(arr):
for SERVER in $var ; { ...; }
for SERVER in "${arr[@]}"; { ...; }
并行 ssh 连接可以这样完成:
cmd="
cpu_info=$(grep processor /proc/cpuinfo | awk 'NF==3{count++} END {printf count}')
mem_info=$(free -g | awk /Mem:/{printf' '})
swap_info=$(free -g | awk /Swap:/{printf' '})
printf \"%-40s %5s %5s %5s\n\" \"$HOSTNAME\" \"$cpu_info\" \"$mem_info\" \"$swap_info\"
"
for SERVER in "${arr[@]}"; {
sshpass -p "$SSHPASS" ssh -q -t -oStrictHostKeyChecking=no "$SERVER" "$cmd" &
}
获取您需要的这些值的另一种解决方案可能是:
$ ssh user@foobar "bash -c \"grep -c '^processor' /proc/cpuinfo; free -g\"" | awk '{if (NR==1) {printf " "} if (=="Mem:") { for (i=1; i<=NF; i++) printf $i " "}; if (=="Swap:") { for (i=1; i<=NF; i++) printf $i " "};}'
user@foobar's password:
4 Mem: 15 2 2 0 10 11 Swap: 15 0 15
最好告诉我们这些“旧”系统中可用的命令或工具是什么。我只习惯于使用脚本中的命令(grep 和 awk)。
对于多个SSH连接,只需将命令行引入for循环即可。
更新:要处理如果机器没有命令 nproc 的问题,只需添加一个 if 条件:
if ! command -v nproc &> /dev/null
then
ssh user@foobar "bash -c \"grep -c '^processor' /proc/cpuinfo; free -g\"" | awk '{if (NR==1) {printf " "} if (=="Mem:") { for (i=1; i<=NF; i++) printf $i " "}; if (=="Swap:") { for (i=1; i<=NF; i++) printf $i " "};}'
else
ssh user@foobar "bash -c \"nproc ; free -g\"" | awk '{if (NR==1) {printf " "} if (=="Mem:") { for (i=1; i<=NF; i++) printf $i " "}; if (=="Swap:") { for (i=1; i<=NF; i++) printf $i " "};}'
fi
我试图了解在远程主机上 运行 以 parallel
方式使用 ssh
执行多个命令的最佳方法,并在挤压警告时在屏幕上显示输出,屏幕上的错误。
此 post 主要与
下面的代码适用于给定的命令,但是我的系统中很少有人真的很旧并且不理解 nproc
命令来获取系统上的处理器数量因此我需要使用 grep -c processor /proc/cpuinfo
如果我在 tmp=$(ssh "$server" bash -c 'grep -c "^processor" /proc/cpuinfo; free -g')
.
也会考虑合并条件,例如如果 nproc
存在,则使用文件 /proc/cpuinfo
来计算 CPU,这只是一件与许多其他事情相似的事情。
因此,如果您有不同的命令子集需要从 commands
和 files
.
#!/bin/bash
read -rsp $'Please Enter password below: ' SSHPASS
export SSHPASS
work() {
server=
# ONE connection
tmp=$(ssh "$server" bash -c 'nproc; free -g')
# parsing later
cpu_info=$(<<<"$tmp" awk 'NR==1')
mem_info=$(<<<"$tmp" awk '/Mem:/{printf }')
swap_info=$(<<<"$tmp" awk '/Swap:/{printf }')
# outputting
printf "%-40s %5s %5s %5s\n" "$server" "$cpu_info" "$mem_info" "$swap_info"
}
export -f work
< /home/user1/mem xargs -P0 -n1 -d'\n' bash -c 'work "$@"' _
我试过下面的想法是 borrowed from 但它只打印 SEREVR
名称,没有其他内容:
#!/bin/bash
read -rsp $'Please Enter password below: ' SSHPASS
export SSHPASS
for SERVER in '$(cat /home/user1/mem)'
do
sshpass -e ssh -q -t -oStrictHostKeyChecking=no $SERVER << EOF
cpu_info=$(grep processor /proc/cpuinfo | awk 'NF==3{count++} END {printf count}')
mem_info=$(free -g | awk /Mem:/{printf' '})
swap_info=$(free -g | awk /Swap:/{printf' '})
printf "%-40s %5s %5s %5s\n" "$server" "$cpu_info" "$mem_info" "$swap_info"
EOF
done | tee 2>/dev/null
我可能有很多错误,请原谅我只是想学习。
编辑注:
我知道会有一个明确的问题,为什么不使用 ssh keys
或 already existed tooling
,比如 ansible,salt 等,原因只是,由于公司安全政策,我们不能使用任何他们没有办法重新发明轮子,但是我们在正常环境中大量使用 Ansible 和其他工具。
首先,这个循环不起作用:
for SERVER in '$(cat /home/user1/mem)'
do
...
done
因为 '',删除 '' 或最好先读取 var 或数组中的主机列表:
var=$(cat /home/user1/mem)
arr=($(cat /home/user1/mem))
并循环这个 var(arr):
for SERVER in $var ; { ...; }
for SERVER in "${arr[@]}"; { ...; }
并行 ssh 连接可以这样完成:
cmd="
cpu_info=$(grep processor /proc/cpuinfo | awk 'NF==3{count++} END {printf count}')
mem_info=$(free -g | awk /Mem:/{printf' '})
swap_info=$(free -g | awk /Swap:/{printf' '})
printf \"%-40s %5s %5s %5s\n\" \"$HOSTNAME\" \"$cpu_info\" \"$mem_info\" \"$swap_info\"
"
for SERVER in "${arr[@]}"; {
sshpass -p "$SSHPASS" ssh -q -t -oStrictHostKeyChecking=no "$SERVER" "$cmd" &
}
获取您需要的这些值的另一种解决方案可能是:
$ ssh user@foobar "bash -c \"grep -c '^processor' /proc/cpuinfo; free -g\"" | awk '{if (NR==1) {printf " "} if (=="Mem:") { for (i=1; i<=NF; i++) printf $i " "}; if (=="Swap:") { for (i=1; i<=NF; i++) printf $i " "};}'
user@foobar's password:
4 Mem: 15 2 2 0 10 11 Swap: 15 0 15
最好告诉我们这些“旧”系统中可用的命令或工具是什么。我只习惯于使用脚本中的命令(grep 和 awk)。
对于多个SSH连接,只需将命令行引入for循环即可。
更新:要处理如果机器没有命令 nproc 的问题,只需添加一个 if 条件:
if ! command -v nproc &> /dev/null
then
ssh user@foobar "bash -c \"grep -c '^processor' /proc/cpuinfo; free -g\"" | awk '{if (NR==1) {printf " "} if (=="Mem:") { for (i=1; i<=NF; i++) printf $i " "}; if (=="Swap:") { for (i=1; i<=NF; i++) printf $i " "};}'
else
ssh user@foobar "bash -c \"nproc ; free -g\"" | awk '{if (NR==1) {printf " "} if (=="Mem:") { for (i=1; i<=NF; i++) printf $i " "}; if (=="Swap:") { for (i=1; i<=NF; i++) printf $i " "};}'
fi