Issue
I have the below script:
bash Script:
#!/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 "$@"' --
The above script runs pretty well for me while running in parallel mode.
Script results:
|------------------------------------------------------------|
|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 |
Concern ?
I have two variables: rhelInfo
and perlInfo
to get store information. But it is using two ssh calls to the servers to get the values.
Could I have only one SSH call to execute multiple commands and set both variables?
Solution
Here is how I do remote data collection using ssh
Some remarks
As this function is intended to collect datas, not to connect host (as they don't stay connected), I've renamed them ;-)
Avoid useless forks! use
printf -v varname ...
instead ofvarname=$(printf ...)
Moved
STDERR
redirection2>/dev/null
at more suited place.use
local
to reserve variables names into function scope.printf
must have correct number of arguments, corresponding to number of%s
see This format string has 3 variable....Don't use
-i
switch togrep
if not needed!
remote_collect() {
local target_host=$1 host_answer rhelInfo perlInfo
{
read -r host_answer
read -r rhelInfo
read -r perlInfo
} < <(
ssh -i /home/zabbix/.ssh/ssh_key "root@${target_host}" \
-o StrictHostKeyChecking=no -o PasswordAuthentication=no \
/bin/sh <<-EOF
hostname
awk 'END{print $7}' </etc/redhat-release
rpm -qa | grep mod_perl
EOF
) 2>/dev/null
if [[ $? -eq 0 ]] ;then
printf "| %-10s | %-14s | %-29s |\n" \
"host_answer" "$rhelInfo" "$perlInfo"
else
printf "| %-10s | %-46s |\n" \
"target_host" "Unable to get the ssh connection"
fi
}
Notice: the EOF
mark could be preceded by tabulations Tab, but not spaces! I've dropped tabulation before posting to ensure they won't be converted in space during cut'n paste.
And the head line could be
printf -v marker '%61s' ''
marker=${marker// /-}
printf "+%s+\n| %-10s | %-14s | %-29s |\n+%s+\n" \
"$marker" "Hostname" "RedHat Version" "Perl Version" "$marker"
+-------------------------------------------------------------+
| Hostname | RedHat Version | Perl Version |
+-------------------------------------------------------------+
| hostok | 6.3 | mod_perl-2.0.4-10.el6_5.armf |
| hostbad | Unable to get the ssh connection |
Pretty table using UFT-8
borders
printf -v sl %31s '';sl=${sl// /$'\U2500'}
printf '%b%-12s%b%-16s%b%-31s%b\n' \
\\U250c "${sl::12}" \\U252c "${sl::16}" \\U252c "$sl" \\U2510 \
\\U2502 ' Hostname' \\U2502 ' RedHat Version' \\U2502 ' Perl Version' \
\\U2502 \\U251c "${sl::12}" \\U253c "${sl::16}" \\U253c "$sl" \\U2524
then:
if [[ $? -eq 0 ]] ;then
printf "\U2502 %-10s \U2502 %-14s \U2502 %-29s \U2502\n" \
"$host_answer" "$rhelInfo" "$perlInfo"
else
printf "\U2502 %-10s \U2502 %-46s \U2502\n" \
"$target_host" " Unable to get the ssh connection"
fi
and finally
# printf -v sl %31s '';sl=${sl// /$'\U2500'} # uncomment if $sl not at main scope
printf '\U2514%s\U2534%s\U2534%s\U2518\n' "${sl::12}" "${sl::16}" "$sl"
should produce:
┌────────────┬────────────────┬───────────────────────────────┐
│ Hostname │ RedHat Version │ Perl Version │
├────────────┼────────────────┼───────────────────────────────┤
│ hostok │ 6.3 │ mod_perl-2.0.4-10.el6_5.armf │
│ hostbad │ Unable to get the ssh connection │
└────────────┴────────────────┴───────────────────────────────┘
Answered By - F. Hauri - Give Up GitHub Answer Checked By - Gilberto Lyons (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.