Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I just wrote the following bash script to check the ping access on list of Linux machines

for M in $list
 do
   ping -q -c 1  "$M" >/dev/null 
          if [[ $? -eq 0 ]]
   then
    echo "($C) $MACHINE CONNECTION OK"
   else
    echo "($C) $MACHINE CONNECTION FAIL"
   fi

   let C=$C+1
done

This prints:

 (1) linux643 CONNECTION OK
 (2) linux72 CONNECTION OK
 (3) linux862 CONNECTION OK
 (4) linux12 CONNECTION OK
 (5) linux88 CONNECTION OK
 (6) Unix_machinetru64 CONNECTION OK

How can I use printf (or any other command) in my bash script in order to print the following format?

 (1) linux643 ............ CONNECTION OK
 (2) linux72 ............. CONNECTION OK
 (3) linux862 ............ CONNECTION OK
 (4) linux12 ............. CONNECTION OK
 (5) linux88 ............. CONNECTION FAIL
 (6) Unix_machinetru64 ... CONNECTION OK
share|improve this question
    
You can do a calculation, $TOTAL (length) - $MASHINE (length) to get the number of dots. Then use printf '.%.s' {1..$DOTS} in each loop iteration. Something like this I think will work. – coffeMug yesterday
    
can you please described your solution as answer – yael yesterday
    
You already have an answer. ;-) – coffeMug yesterday
    
up vote 8 down vote accepted

Using parameter expansion to replace spaces resulting from %-s by dots:

#!/bin/bash
list=(localhost google.com nowhere)
C=1
for M in "${list[@]}"
do
    machine_indented=$(printf '%-20s' "$M")
    machine_indented=${machine_indented// /.}

    if ping -q -c 1  "$M" &>/dev/null ;  then
        printf "(%2d) %s CONNECTION OK\n" "$C" "$machine_indented"
    else
        printf "(%2d) %s CONNECTION FAIL\n" "$C" "$machine_indented"
    fi
    ((C=C+1))
done
share|improve this answer
    
WOW , let me check and I will update soon .......................... – yael yesterday
1  
Heh, clever! A couple of pedantic points: i) the %2d is adding a needless space inside the parentheses (although it might be useful when $list >=10); ii) to get the OP's exact output, you might want to add machine_indented=${machine_indented/../ .} to add an extra space before the first .. As I said, pedantic. – terdon yesterday
    
hi Choroba , can you please consider terdon remarks in your answer ? – yael yesterday
    
@yael: It should be now easy for you to tweak the solution :-) – choroba yesterday
    
BTW - why to add & before >/dev/null ? – yael yesterday

for m in $list is zsh syntax. In bash it would be for i in "${list[@]}".

bash doesn't have padding operators. You can do padding with printf but only with spaces, not arbitrary characters. zsh has padding operators.

#! /bin/zsh -
list=(
  linux643
  linux72
  linux862
  linux12
  linux88
  Unix_machinetru64
)
c=0
for machine in $list; do
  if ping -q -c 1 $machine >& /dev/null; then
    state=OK
  else
    state=FAIL
  fi
  printf '%4s %s\n' "($((++c)))" "${(r:25::.:):-$machine } CONNECTION $state"
done

The padding operator is ${(r:25:)parameter} to right-pad with length 25 with spaces or ${(r:25::string:)parameter} to right-pad with any string instead of space.

We also use printf '%4s' to left-pad the (x) with spaces. We could have used ${(l:4:):-"($((++c)))"} instead. A notable difference though is that if the string is more than 4 characters long, ${(l)} would truncate it, while it would overflow with printf.

share|improve this answer

The %s format specifier can take a precision (%.20s for example), and just as when you want to output a float value to a certain precision (with %.4f for example), the output will be at most that many characters from the given string argument.

So create a string that contains the machine name and enough dots to run out of dots:

C=0
for M in vboxhost ntp.stupi.se example.com nonexistant; do
   if ping -q -c 1  "$M" >/dev/null 2>&1; then
       OK="OK"
   else
       OK="FAIL"
   fi

   printf "(%d) %.20s CONNECTION %s\n" \
       $(( ++C )) "${M} ...................." $OK

done

Output:

(1) vboxhost ........... CONNECTION OK
(2) ntp.stupi.se ....... CONNECTION OK
(3) example.com ........ CONNECTION OK
(4) nonexistant ........ CONNECTION FAIL
share|improve this answer

With stuff stolen from @choroba's answer:

#!/bin/bash 
list=(linux643 linux72 google.com linux862 linux12 linux88 unix_machinetru64) 
C=1 
readonly TOTAL=50 
for M in "${list[@]}" 
do 
    DOTS=$(( TOTAL - ${#M} ))
    ping -q -c 1  "$M" &>/dev/null 

    if (($?)) ;  then 
        printf "(%d) %s" "$C" "$M" ; printf "%0.s." $(seq 1 $DOTS) ; printf " CONNECTION FAILED\n" 
    else 
        printf "(%d) %s" "$C" "$M" ; printf "%0.s." $(seq 1 $DOTS) ; printf " CONNECTION OK\n"  
    fi 
    ((C=C+1)) 
done 
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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