skip to Main Content

First time post, please forgive any missing information.

I have a script that is supposed to work with icinga. I need icinga to log into my Linux box and run a command like "script ". The script will then run a command to that hostname like sudo /etc/init.d/apache2 status then report back "running or unused" and an exit status of 0 or 2.
I’m wondering how I could add another command and have it one or the other run depending on what hostname it’s given. Half of them need apache2 to be running and the other half need to have a process called dss to be running. I’d rather not have two separate scripts. Here is the working script and sorry it’s sloppy but I haven’t done any clean up and I’m not real good at bash yet.

so the user would run the script ./chkdss2 or

#!/bin/bash
ec=0
ec1=2
var3=run
var4=unused

for host in "$@"
do
  var1=`ssh $host sudo /etc/init.d/dss status|awk '{print $6}'`
  var2="$( echo $var1 | cut -c 3-5 )"
if [[ "$var2" == "$var3" ]]; then
    echo "$host is running"
    echo $ec
  else
    echo "$host is not running"
    echo $ec1
fi
done

3

Answers


  1. Chosen as BEST ANSWER

    I was able to take a little bit from the answers I received and put together something that works well. Thank you all for your answers.

    for host in "$@"
    do
        case "$host" in
           ('vho1uc1-primary'|'vho1uc2-backup'|'vho2uc1-primary'|'vho2uc2-backup'|'vho3uc1-primary'|'vho3uc2-backup'|'vho10uc1-primary')
              var1=`ssh "$host" sudo /etc/init.d/apache2 status|awk '{print $4}'`
              var2="$( echo $var1 | cut -c 3-5 )"
                if [[ "$var2" == "$var3" ]]; then
              echo "Apache2 on $host is running"
              echo "0"
                else
              echo "Apache2 on $host is not running"
              echo "2"
              fi
              ;;
           *)
        esac
    done
    

  2. There are a couple ways to test if a particular hostname is for apache or dss. You only need to have a list of hostnames for each case, and check if the received hostnames are included in said lists.

    Method 1: using arrays

    #!/bin/bash
    
    # Method 1, using array lists of hosts
    apachehosts=('ap1' 'ap2' 'ap3')
    dsshosts=('dss1' 'dss2' 'dss3')
    
    for host in "$@"
    do
        if printf '%sn' "${apachehosts[@]}" | grep -Fxq "$host"
        then
            echo "$host: APACHE HOST"
        elif printf '%sn' "${dsshosts[@]}" | grep -Fxq "$host"
        then
            echo "$host: DSS HOST"
        else
            echo "ERROR, $host: unknown host"
        fi
    done
    

    To modify the lists of hosts, simply add or remove values in the declaration of arrays apachehosts and dsshosts.


    Method 2: using case

    #!/bin/bash
    
    # Method 2, using case
    for host in "$@"
    do
        case "$host" in
            'ap1'|'ap2'|'ap3')
                echo "CASE, $host: APACHE HOST"
                ;;
            'dss1'|'dss2'|'dss3')
                echo "CASE, $host: DSS HOST"
                ;;
            *)
                echo "ERROR CASE, $host: unknown host"
                ;;
        esac
    done
    

    Here, you edit the patterns in each case.


    Method 3: using if

    #!/bin/bash
    
    # Method 3, using if
    for host in "$@"
    do
        if [[ "$host" == 'ap1' || "$host" == 'ap2' || "$host" == 'ap3' ]]
        then
            echo "IF, $host: APACHE HOST"
        elif [[ "$host" == 'dss1' || "$host" == 'dss2' || "$host" == 'dss3' ]]
        then
            echo "IF, $host: DSS HOST"
        else
            echo "IF, $host: unknown host"
        fi
    done
    

    Here you modify the if conditions. I prefer the other methods, since this one is more complicated to edit, it is not as clear, especially if your list of hosts is long.


    Method 4: condition on the hostnames

    If you are lucky, there is some pattern to your hostnames. Ex. all apache servers start with letters ap, all your dss servers include dss in the name, …

    You can then simply use 2 if statements to decide which is which.

    #!/bin/bash
    
    # Method 4, patterns
    for host in "$@"
    do
        if [[ $(echo "$host" | grep -c -e "^ap") -ne 0 ]]
        then
            echo "PATTERNS, $host: APACHE HOST"
        elif [[ $(echo "$host" | grep -c -e "dss") -ne 0 ]]
        then
            echo "PATTERNS, $host: DSS host"
        else
            echo "PATTERNS, $host: unknown host"
        fi
    done
    

    Note: hostname apdss1 would come out as an Apache server here. Previous methods would respond "unknown host". You patterns must be strict enough to avoid mismatches.

    Login or Signup to reply.
  3. I had a similar task to get few report items using single ssh request.

    I had to retrieve in singel ssh command:

    1. Full hostname (FQDN)
    2. Linux version
    3. IP address of its Docker host if exist, or "none"

    I got my script to work in 3 stage.

    1. Get multiple lines of information from remote host

    ssh -q dudi-HP-Compaq-Elite-8300-MT  <<< '
    date +%F:%T   # line 1: time stamp
    hostname -f     # line 2: hostname 
    awk  "/DESCR/{print $3}" /etc/lsb-release # line 3 : host linux distribution version
    ip a | awk "/inet / && !/127.0.0.1/{sub("/.*","",$2);printf("%s ", $2)}"      # line 4: list IP address to the host
    '
    

    Results:

    2022-03-05:22:22:21
    dudi-HP-Compaq-Elite-8300-MT
    20
    192.168.2.111 192.168.122.1 172.17.0.1
    

    2. Process multiple lines of information from remote host

    Read lines of information from remote host, into an array sshResultsArr.

    readarray -t sshResultsArr < <(ssh -q dudi-HP-Compaq-Elite-8300-MT  <<< '
    date +%F:%T   # line 1: time stamp
    hostname -f     # line 2: hostname 
    awk  "/DESCR/{print $3}" /etc/lsb-release # line 3 : host linux distribution version
    ip a | awk "/inet / && !/127.0.0.1/{sub("/.*","",$2);printf("%s ", $2)}"      # line 4: list IP address to the host
    ')
    hostname=${sshResultsArr[1]}
    osVersion=${sshResultsArr[2]}
    hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
    hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"
    
    printf "%s t OS version: %s t has Docker IP: %sn" "$hostname" "$osVersion" "$hasDockerIp"
    

    Result:

    dudi-HP-Compaq-Elite-8300-MT     OS version: 20          has Docker IP: 172.17.0.1
    

    3. Process each remote host in a loop

    #!/bin/bash
    for host in "$@"; do
      readarray -t sshResultsArr < <(ssh -q $host  <<< '
      date +%F:%T   # line 1: time stamp
      hostname -f     # line 2: hostname 
      awk  "/DESCR/{print $3}" /etc/lsb-release # line 3 : host linux distribution version
      ip a | awk "/inet / && !/127.0.0.1/{sub("/.*","",$2);printf("%s ", $2)}"      # line 4: list IP address to the host
      ')
      hostname=${sshResultsArr[1]}
      osVersion=${sshResultsArr[2]}
      hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
      hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"
    
      printf "%s t OS version: %s t has Docker IP: %sn" "$hostname" "$osVersion" "$hasDockerIp"
    done
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search