1

Here I'm trying to ssh to multiple servers remotely and check whether any processes running on those servers and wait until the process to get finished.

while read ip name
do
  process=alive
  while [[ "$process" == "alive" ]]
  do
    process=dead
    (if [ 1 -eq "$(echo "$(ssh ubuntu@$ip "top -b -n2 -d 0.5|grep Cpu|awk '{print \$2+\$4}'|tail -n1") > 1" | bc)" ];then
      echo "Process is running on $ip"
      process=alive
      sleep 10
      continue 
    else
      echo "Process is not running on $ip"
      echo "I run some other commands here"
    fi) &
  done
done < ips
wait `jobs -p`

The code is breaking after 'continue' statement.

Here is the output

+ read ip name
+ process=alive
+ [[ alive == \a\l\i\v\e ]]
+ process=dead
+ [[ dead == \a\l\i\v\e ]]
+ read ip name
+ process=alive
+ [[ alive == \a\l\i\v\e ]]
+ process=dead
+ [[ dead == \a\l\i\v\e ]]
+ read ip name
++ jobs -p
++ bc
+ wait 31090 31091
+++ ssh ubuntu@249.X.X.X 'top -b -n2 -d 0.5|grep Cpu|awk '\''{print $2+$4}'\''|tail -n1'
++ bc
+++ ssh ubuntu@256.X.X.X 'top -b -n2 -d 0.5|grep Cpu|awk '\''{print $2+$4}'\''|tail -n1'
++ echo '20.7 > 1'
+ '[' 1 -eq 1 ']'
+ echo 'Process is running on 249.X.X.X'
Process is running on 249.X.X.X
+ process=alive
+ sleep 10
++ echo '14.6 > 1'
+ '[' 1 -eq 1 ']'
+ echo 'Process is running on 256.X.X.X'
Process is running on 256.X.X.X
+ process=alive
+ sleep 10
+ continue
+ continue
1

Replace ssh with ssh -n to stop reading from stdin (file ips).


See: man ssh

1

Using ssh -n to redirect /dev/null into the standard input of ssh should solve the immediate issue though. Without -n, ssh will read from the ips file. But there are other unnecessary things that you do in your code.

Corrected code:

while read ip name; do
    (
    while true; do
        if ssh -n "ubuntu@$ip" top -b -n2 -d 0.5 | awk '/Cpu/ && n++ { exit($2+$4 > 1) }'
            printf 'Process is running on %s\n' "$ip"
            sleep 10
        else
            printf 'Process is not running on %s\n' "$ip"
            echo 'I run some other commands here'
            break
       fi
    done
    ) &
done <ips

wait

I've simplified your code a bit by

  • not trying to run more than top on the remote host,
  • using the exit value of awk directly with if,
  • using break to break out of the (now) infinite loop,
  • running that loop in the background job, not only the if statement, and
  • using wait without any arguments to wait for all background processes.

Another variant that eliminates the need for the if statement all-together:

while read ip name; do
    (
    while ssh -n "ubuntu@$ip" top -b -n2 -d 0.5 | awk '/Cpu/ && n++ { exit($2+$4 > 1) }'
    do
        printf 'Process is running on %s\n' "$ip"
        sleep 10
    done
    printf 'Process is not running on %s\n' "$ip"
    echo 'I run some other commands here'
    ) &
done <ips

wait

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.