我在远程主机上运行多个命令。如果我直接在 ssh 脚本中传递命令,它就可以工作,一旦我从另一个脚本作为参数传递它,它就会给我第一个主机的结果,并在登录后立即超时。如何从另一个脚本传递命令并使其正常工作,或者我的 ssh 脚本仅在一台主机上执行命令的原因是什么?
#Linux ssh
My_ssh_function () {
sudo sshpass -p "$1" ssh -q -o StrictHostKeyChecking=no root@"$2" "$command_linux"
}
export -f My_ssh_function
export -p command_linux
export -p file_with_targets_linux
export -p passwords
parallel -j 2 --tag My_ssh_function :::: "$passwords" "$file_with_targets_linux"
我从另一个文件传递的命令:(只要我不将它从另一个脚本发送到上面的脚本,就可以正常工作)
""/sbin/dmidecode | /usr/bin/grep "Product Name:" | /usr/bin/awk '{print $4, $5}' > /tmp/result && free -h --si |grep Mem | awk '{print $2}' >> /tmp/result && dmidecode -s system-serial-number >> /tmp/result && hostname |awk -F"." '{print $1}' >> /tmp/result && cat /tmp/result |xargs""
parallel: Warning: My_ssh_function host_password_string 135.121.157.80 parallel: Warning: This job was killed because it timed out:
答案1
您从示例中遗漏了一些内容:该示例并不完整,因为如果您没有--timeout
.
也就是说,您应该测试它My_ssh_function
是否按预期工作。
所以试试这个:
# remove --tag from parallel
parallel --dryrun ... > myfile.sh
# Does myfile.sh contain what you expect now?
cat myfile.sh
# Does it run as you expect?
bash myfile.sh
如果它对某些主机有效,我想sshpass ... ssh
对某些主机来说会失败。
如果它对任何主机都不起作用,我猜你的引用是错误的。
我个人会:
- 删除
sudo
:目前还不清楚为什么需要sshpass
以 root 身份运行。 - 不使用
sshpass
。相反,使用ssh-copy-id
一次即可让您的用户登录。使用ssh-agent
您的 ssh 密钥上仍然有一个密码,但登录时不必输入它。这样,获得备份访问权限的犯罪分子~/.ssh
将无法使用您的密钥。 - 设置完成后,您应该能够让 GNU Parallel 直接使用
--ssh
和进行登录,--slf
并使用--onall
或--nonall
运行命令。 - 当这种方法有效时,您可能会考虑将长单行脚本转换为 bash 函数,然后将
env_parallel
其复制到远程计算机。
像这样的东西:
at_startup() {
# Add sshkey to sshagent unless already done
if [ -e ~/.ssh/SSH_AUTH_SOCK ] ; then
export SSH_AUTH_SOCK=`cat ~/.ssh/SSH_AUTH_SOCK`
fi
if [ -e ~/.ssh/SSH_AGENT_PID ] ; then
export SSH_AGENT_PID=`cat ~/.ssh/SSH_AGENT_PID`
fi
if ssh-add -l ; then
true
else
eval `ssh-agent` ssh-add ~/.ssh/id*[^b] &&
echo $SSH_AUTH_SOCK > ~/.ssh/SSH_AUTH_SOCK &&
echo $SSH_AGENT_PID > ~/.ssh/SSH_AGENT_PID
fi
}
setup_ssh_keys_once() {
setupone() {
sshpass -p "$1" ssh-copy-id -o StrictHostKeyChecking=no root@"$2"
}
export -f setupone
parallel setupone :::: "$passwords" "$file_with_targets_linux"
}
env_parallel --session
command_linux() {
/sbin/dmidecode | /usr/bin/grep "Product Name:" | /usr/bin/awk '{print $4, $5}' > /tmp/result &&
free -h --si |grep Mem | awk '{print $2}' >> /tmp/result &&
dmidecode -s system-serial-number >> /tmp/result &&
hostname | awk -F"." '{print $1}' >> /tmp/result &&
cat /tmp/result |xargs
}
# Yes: env_parallel can copy a function to a remote server - even if it is not exported
env_parallel --ssh 'ssh -l root' --slf "$file_with_targets_linux" --nonall command_linux