123

I am trying to do an IF statement from the output of an executed commmand. Here is how I am trying to do it, but it doesn't work. Does anyone know the right way to do this?

if [ "`netstat -lnp | grep ':8080'`" == *java* ]; then
  echo "Found a Tomcat!"
fi

EDIT: I wonder if there is a way to do it by capturing exit code?

1
  • Regarding your recent edit: You are capturing the exit code, of the [ utility. The currently accepted answer captures the exit code of [[, and the other answer captures the exit code of the grep -q pipeline.
    – Kusalananda
    Commented Oct 17, 2022 at 17:46

6 Answers 6

137

Use the bash [[ conditional construct and prefer the $(<command>) command substitution convention. Additionally, [[ prevents word splitting of variable values therefore there is no need to quote the command substitution bit..

if [[ $(netstat -lnp | grep ':8080') == *java* ]]; then
  echo "Found a Tomcat!"
fi
1
  • Additionally, [[ prevents word splitting of variable values therefore there is no need to quote the command substitution bit Can you elaborate on this concept? I don't see any variables in here: what would an example look like where this made a difference? Commented Sep 13, 2023 at 23:10
53

Another alternative is to simply test the exit status of grep itself, which will return false (non-zero) if there was no match and true (zero) if there was one, by not using the [ command.

if netstat -lntp | grep -q ':8080.*java'; then
    echo "Found a Tomcat!"
fi
2
  • 1
    Newb here: is this "idiomatic" bash or is it "clever code"? Commented Sep 13, 2023 at 23:12
  • @DanielKaplan I'd personally say that this is "idiomatic." [[ is just a program (technically a builtin but w/e) and so is if. So, if [[ ... ]] is just checking the exit status of the [[ command, and then doing something else based on that result. Perfectly reasonable imo to replace [[ with something else. Commented Aug 22 at 15:23
11

Even more simple,

netstat -lntp | grep ':8080.*java' > /dev/null && command

If you just want to do one thing.

4

You can do more precise, yet simple, matching with awk.

if netstat -lnp | awk '$4 ~ /:8080$/ && $7 ~ /java/ {exit(0)} END {exit(1)}'; then …

To match the structure of your command more closely, the portable way of doing wildcard matching on a string in a shell is with the case construct.

case "$(netstat -lnp | grep ':8080')" in
  *java*)  echo "Found a Tomcat!";;
esac
1

Here's how I did it in a script that determines whether my music player is open or not, and if a song is playing if it is open.

rbstatus=$(rhythmbox-client --print-playing)

pgrep -x rhythmbox >/dev/null && if [ "$rbstatus" = "-" ]; then
   echo "No music playing"
else
   rhythmbox-client --print-playing
fi || echo "Music player is Closed."
2
  • Welcome on U&L! A side note: consider that &&/|| is not equivalent to if/else. Your code will print "Music player is Closed." even if pgrep succeeds and the command in the else block fails (returns a non-zero status) for some reason (likely not a real issue in your case, of course).
    – fra-san
    Commented Aug 29, 2020 at 21:13
  • Nice alternative way of doing it. :-)
    – djangofan
    Commented Oct 19, 2022 at 23:02
1

A simple and logic way:

netcat -zw3 localhost 8000 && echo 'tomcat is up'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .