6

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"?

6

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)!"
  • it is a cool solution!Thanks! but I want to find the way to do it with if-then-else and grep. – fuser Dec 2 '15 at 9:31
  • You can use that awk script with if. i'll edit my answer to show an example. – cas Dec 2 '15 at 9:33
  • I am not good at awk. Could you tell me please what this part of code $2 ~ in awk means ? – fuser Dec 2 '15 at 9:51
  • 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 Dec 2 '15 at 10:11
0
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"}))"

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.