126

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
  • 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. Commented Oct 17, 2022 at 17:46

6 Answers 6

140

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
55

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, 2024 at 15:23
12

Even more simple,

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

If you just want to do one thing.

5

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). Commented Aug 29, 2020 at 21:13
  • Nice alternative way of doing it. :-) 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.