PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, August 3, 2022

[FIXED] How to create a granular bash script with multiple variables with ssh connections

 August 03, 2022     bash, html-table, shell, variables     No comments   

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 of varname=$(printf ...)

  • Moved STDERR redirection 2>/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 to grep 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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing