114

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?

djangofan
  • 4,002
  • 5
  • 21
  • 19
  • 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 Oct 17 '22 at 17:46

6 Answers6

127

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
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
iruvar
  • 16,515
  • 8
  • 49
  • 81
49

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
Gilles Quénot
  • 31,569
  • 7
  • 64
  • 82
Random832
  • 10,476
  • 1
  • 34
  • 40
9

Even more simple,

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

If you just want to do one thing.

Rob Bos
  • 4,250
  • 1
  • 11
  • 12
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
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
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."
fra-san
  • 9,931
  • 2
  • 21
  • 42
  • Welcome on U&L! A side note: consider that [`&&`/`||` is not equivalent to `if`/`else`](https://unix.stackexchange.com/q/335832/315749). 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 Aug 29 '20 at 21:13
  • Nice alternative way of doing it. :-) – djangofan Oct 19 '22 at 23:02
1

A simple and logic way:

netcat -zw3 localhost 8000 && echo 'tomcat is up'
Gilles Quénot
  • 31,569
  • 7
  • 64
  • 82