LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   writing script in bash (https://www.linuxquestions.org/questions/linux-newbie-8/writing-script-in-bash-944040/)

sumeet inani 05-09-2012 06:42 AM

writing script in bash
 
Hi ,
I don't know much programming .
I want to make following program

for variable k in list 58 , 62 ,67 ,... (this is a peculiar list of 30 numbers)
do
{
l="$(ping -c 1 192.168.8.$k | grep -i ttl)"
if [ $? -eq 0 ]
then
echo "found\n"
else
echo "\nNot found 192.168.8.$k"
fi
}

I got some pieces from hither and thither .
My aim is to ping 192.168.8.something & report which where not found .
Also somebody told me dollar is better than back ticks.

bradvan 05-09-2012 07:17 AM

This should do it.

Code:

#!/bin/bash
for k in 58 62 67 87 123; do
  l = $(/bin/ping -c 1 192.168.8.${k} | /bin/grep ttl)
  if [ "X${l}" = "X" ]; then
      echo "Address 192.168.8.${k} does not answer."
  else
      echo "Address 192.168.8.${k} does answer."
  fi
done


catkin 05-09-2012 07:26 AM

Quote:

Originally Posted by sumeet inani (Post 4674162)
Also somebody told me dollar is better than back ticks.

Yes -- $( <command(s)> ) is preferred over ` <command(s)> ` for reasons explained here.

David the H. 05-09-2012 12:00 PM

As long as your shell is bash or ksh, you really should be using [[..]] instead, or ((..)) for arithmetical comparisons. Then you don't need to use that old "[ "X${l}" = "X" ]" trick.


http://mywiki.wooledge.org/ArithmeticExpression
http://mywiki.wooledge.org/BashFAQ/031
http://wiki.bash-hackers.org/commands/classictest
http://wiki.bash-hackers.org/syntax/...nal_expression


However, I'm guessing we don't really want any of the output from grep, just whether it found anything. In which case you don't even need a test at all. Just silence its output and check its exit code directly.

Code:

#!/bin/bash

for k in 58 62 67 87 123 ; do

  if  ping -c1 "192.168.8.$k" | grep -q ttl ; then

        echo "Address 192.168.8.$k answered."

  else

        echo "Address 192.168.8.$k didn't answer."

  fi

done

exit


TobiSGD 05-09-2012 12:06 PM

You don't need the grep at all, since ping exits with exitcode 1 if it gets no answer to its echo requests.

David the H. 05-09-2012 12:25 PM

That's true, isn't it. It dawned on me after I posted.

But from what I can see, ping doesn't seem to have a truly silent mode (if it does, correct me please). You'd have to redirect the output away.

Code:

if  ping -c1 "192.168.8.$k" &>/dev/null ; then

cbtshare 05-10-2012 12:50 AM

to me you dont even need the
Quote:

if ping
, I think what Tobi means is to if the exit status, so :
Quote:

ping -c1 "192.168.8.$k"
if [ $? = 0]

sumeet inani 05-10-2012 01:43 AM

Is it possible to write colorful text (only for some outputs) using echo command ?
In bash I used to set default prompt using variable PS1 .

sumeet inani 05-10-2012 01:49 AM

okay . i think . This will help --> http://hacktux.com/bash/colors

Also I will take some time to understand all useful suggestions .

grail 05-10-2012 02:25 AM

@cbtshare - Running the command and then testing the return value would be two lines to do the same thing as let the "if" command test the return for you ... so no your second option would
not generally be preferred.

bradvan 05-10-2012 05:14 AM

David, thanks for the links. It's always great to learn new things. I've been using the bourne shell almost since it came out and am not totally familiar with all the new bash'isms. :)

sumeet inani, another thought that will probably make it easier to read the results: Define two variables that point to two files. Then just echo ${k} to the appropriate file. That way you will have a list of answered totally separate from the unanswered.
Code:

#!/bin/bash
ANS=/tmp/answered
NO=/tmp/noanswer
for k in 58 62 67 87 123; do
  if /bin/ping -c 1 192.168.8.${k} | /bin/grep ttl; then
      echo "${k}" >> ${ANS}
  else
      echo "${k}" >> ${NO}
  fi
done


cbtshare 05-10-2012 09:58 AM

Quote:

Originally Posted by grail (Post 4674852)
@cbtshare - Running the command and then testing the return value would be two lines to do the same thing as let the "if" command test the return for you ... so no your second option would
not generally be preferred.

Ah, ok ,well if its shorter code is the prefence, then the entire 'if' statement can be removed and subsituted with parameters.Your right efficiency is better,atleast for long code,but for stuff like this,I opt for the ABC's,nicer to read :)

grail 05-10-2012 03:34 PM

Quote:

then the entire 'if' statement can be removed and subsituted with parameters.
Sorry, you lost me ... could you explain this method?

Also, my preference was not necessarily for shorter code, but at the end of the day we are doing the exact same process. "if" itself is a function and therefore tests the exit result
of other functions, like [ or [[, so the following are both the same:
Code:

if ping -c1 192.168.8.$k &>/dev/null; then

ping -c1 192.168.8.$k &>/dev/null
if [[ $? == 0 ]]; then # that is without going into semantics that we should use (()) here :)


cbtshare 05-11-2012 12:16 AM

Yea I get what your saying as having the test for the exist code status makes it bulkier and some what redundant because you could have added into one line (the ping and the 'if')to achieve the same result.

I was referring to somtten like this, and no need for the if which makes it shorter
Quote:

for k in 8 8 67 87 123
do
ping=$(ping -c 1 192.168.1.$k | grep -E ttl=) >/dev/null

result=${ping:? didnt answer $(mail -s root "server .$k is down,please fix and run command again")}
echo ".$k answered fine"
done
exit 0


All times are GMT -5. The time now is 11:11 PM.