gpt4 book ai didi

bash - 如何使用 ssh 连接创建具有多个变量的粒度 bash 脚本

转载 作者:行者123 更新时间:2023-12-05 01:05:03 24 4
gpt4 key购买 nike

我有以下脚本:

脚本:

#!/bin/bash
###########
printf "\n"
marker=$(printf "%0.s-" {1..60})
printf "|$marker|\n"
printf "|%-10s | %-13s | %-29s |\n" "Hostname" "RedHat Vesrion" "Perl Version"
printf "|$marker|\n"

remote_connect() {
target_host=$1
marker=$(printf "%0.s-" {1..60})
rhelInfo=$(ssh -i /home/zabbix/.ssh/ssh_key "root@${target_host}" -o StrictHostKeyChecking=no -o PasswordAuthentication=no cat /etc/redhat-release| awk 'END{print $7}')
perlInfo=$(ssh -i /home/zabbix/.ssh/ssh_key "root@${target_host}" -o StrictHostKeyChecking=no -o PasswordAuthentication=no "rpm -qa | grep -i mod_perl")
if [[ $? -eq 0 ]]
then
printf "|%-10s | %-13s | %-20s |\n" "$target_host" "$rhelInfo" "$perlInfo"
else
printf "|%-10s | %-13s | %-20s |\n" "$target_host" "Unable to get the ssh connection"
fi
} 2>/dev/null
export -f remote_connect
< /home/zabbix/hostsList.txt xargs -P30 -n1 -d'\n' bash -c 'remote_connect "$@"' --

上面的脚本在并行模式下运行时对我来说运行得很好。

脚本结果:

|------------------------------------------------------------|
|Hostname | RedHat Vesrion | Perl Version |
|------------------------------------------------------------|
|foxnl41 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl84 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl42 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl63 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl10 | 6.7 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl55 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl95 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |
|foxnl85 | 6.9 | mod_perl-2.0.4-11.el6_5.x86_64 |

担心?

我有两个变量:rhelInfoperlInfo 来获取商店信息。但它使用两次 ssh 调用服务器来获取值。

我可以只有一个 SSH 调用来执行多个命令并设置两个变量吗?

最佳答案

Could I have only one SSH call to execute multiple commands and set both variables?

当然。你可以这样做:

# this looks too long - so a function
_ssh() {
ssh -i /home/zabbix/.ssh/ssh_key \
-o StrictHostKeyChecking=no \
-o PasswordAuthentication=no \
"root@$target_host" \
"$@"
}
export -f _ssh

# the function to-be-executed on the remote
remotework() {
rhelinfo=$(awk 'END{print $7}' /etc/redhat-release)
perlinfo=$(rpm -qa | grep -i mod_perl)
# output elements separated by byte 0x01
printf "%s\001" "$rhelinfo" "$perlinfo"
}
export -f remotework

remote_connect() {
# execute bash on the remote
# with `remotework` function serialized
# and execute the `remotework` function
# properly `printf %q` quote everything for unquoting done by ssh+remote shell
tmp=$( _ssh "$(printf "%q " bash -c "$(declare -f remotework); remotework")" )
# split the output of ssh by byte 0x01
{
IFS= read -d $'\x01' -r rhelInfo &&
IFS= read -d $'\x01' -r perlInfo
} <<<"$tmp"
}

或类似的变体。基本上 ssh 为您提供双向数据流 - 您可以在中间使用分隔符(“自定义协议(protocol)”)流式传输任何内容,然后在该分隔符上拆分数据。 IE。问题不仅限于 ssh - 研究 bash 中的数据序列化/反序列化。上面我选择了字节 0x01 作为分隔符 - 您可以使用具有唯一 uuid 的单独行,使用 base64 -w0 将数据转换为单行,或类似或使用其他格式。

remotework() {
awk ... | base64 -w0
echo ' '
rpm ... | base64 -w0
echo
}
...
IFS=' ' read -r rhelInfo perlInfo <<<"$tmp"
rhelInfo=$(<<<"$rhelInfo" base64 -d)
perlInfo=$(<<<"$perlInfo" base64 -d)

你也可以用 declare -p 序列化变量,然后 eval 他们 - 在我看来这更危险,所以最好使用分隔符。

关于bash - 如何使用 ssh 连接创建具有多个变量的粒度 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71162141/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com