Sign up ×
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.

I am trying to create script which can let me to put number of port as parameter and then find the name of service for this port. Here is the script:

#!/bin/bash

grep -E "\W$1\/" /etc/services | awk '{ print $1 }'
if [ $? -eq 0 ]; then 
echo "Service(s) is(are) found correctly!"
else
echo "There is(are) no such service(s)!"
fi

Everything works perfectly but there is one problem. If I type such port as 99999 (or another fiction port) - "exit status" for grep -E "\W$1\/" /etc/services | awk '{ print $1 }' also will be 0. In this way all results of my scripts will be correct and else statement in my script won't work. What am I going to do to find the solution to this problem and let my else works fine with "exit status"?

share|improve this question

3 Answers 3

up vote 6 down vote accepted

You don't need grep here at all, awk can do the pattern match on the port number.

awk can also keep track of whether the port was found or not and exit with an appropriate exit code.

For example:

$ port=23
$ awk  '$2 ~ /^'"$port"'\// {print $1 ; found=1} END {exit !found}' /etc/services 
telnet
$ echo $?
0

$ port=99999
$ awk  '$2 ~ /^'"$port"'\// {print $1 ; found=1} END {exit !found}' /etc/services 
$ echo $?
1

The exit !found works because awk variables default to zero (or true) if they haven't previously been defined - exit !0 is exit 1. So if we set found=1 when we match then exit !found in the END block is exit 0.

Here's how to use that awk script with your if/then/else.

#!/bin/bash

awk  '$2 ~ /^'"$1"'\// {print $1 ; found=1} END {exit !found}' /etc/services 
if [ $? -eq 0 ]; then 
    echo "Service(s) is(are) found correctly!"
else
    echo "There is(are) no such service(s)!"
fi

You can also do it like this:

if awk  '$2 ~ /^'"$1"'\// {print $1;found=1} END{exit !found}' /etc/services ; then 
    echo "Service(s) is(are) found correctly!"
else
    echo "There is(are) no such service(s)!"
fi

Or even like this:

awk  '$2 ~ /^'"$1"'\// {print $1 ; found=1} END {exit !found}' /etc/services \
  && echo "Service(s) is(are) found correctly!" \
  || echo "There is(are) no such service(s)!"
share|improve this answer
    
it is a cool solution!Thanks! but I want to find the way to do it with if-then-else and grep. – fuser yesterday
    
You can use that awk script with if. i'll edit my answer to show an example. – cas yesterday
    
I am not good at awk. Could you tell me please what this part of code $2 ~ in awk means ? – fuser yesterday
1  
That compares ONLY the second field of /etc/services against the port regex, preventing any possibility of spurious matches from any comments on the input lines. that's not a big risk with this particular input file but as a general rule if you know what you're searching for is in a particular field, it's good practice to restrict the search to just that field. – cas 23 hours ago

invert your pipeline.

grep -E "\W$1\/" /etc/services | awk '{ print $1 }' will always return 0 cause it gets $? from awk, not grep.

just rewrite it as awk '{ print $1 }' | grep -E "\W$1\/" /etc/services, and you will get $? from grep.

share|improve this answer
    
in this way I'll get the whole line output in spite of the name of the service – fuser yesterday
1  
@dcat you meant ` awk '{ print $1 }' /etc/services | grep -E "\W$1\/" ` ? – Archemar yesterday
x=$(sed -ne"\|^\([^ ]*\) *\($1\)/.*|!d;h;s//\2/p;g" \
        -e's||Found service: \1|w /dev/fd/2' -eq </etc/services)
exit "$((!${x:?No service found for: "$1"}))"
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.