Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash shell `if` command returns something `then` do something

I am trying to do an if/then statement, where if there is non-empty output from a ls | grep something command then I want to execute some statements. I am do not know the syntax I should be using. I have tried several variations of this:

if [[ `ls | grep log ` ]]; then echo "there are files of type log";
like image 460
Billy Moon Avatar asked Apr 29 '12 13:04

Billy Moon


People also ask

How can I determine whether a command executed successfully?

This works by using the (( )) arithmetic mode, so if the command returned success , i.e. $? = 0 then the test evaluates to ((0)) which tests as false , otherwise it will return true . but it's already not much shorter than the first example. After that $? is 0 if success, otherwise failure.

What does $@ do bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc.


2 Answers

Well, that's close, but you need to finish the if with fi.

Also, if just runs a command and executes the conditional code if the command succeeds (exits with status code 0), which grep does only if it finds at least one match. So you don't need to check the output:

if ls | grep -q log; then echo "there are files of type log"; fi

If you're on a system with an older or non-GNU version of grep that doesn't support the -q ("quiet") option, you can achieve the same result by redirecting its output to /dev/null:

if ls | grep log >/dev/null; then echo "there are files of type log"; fi

But since ls also returns nonzero if it doesn't find a specified file, you can do the same thing without the grep at all, as in D.Shawley's answer:

if ls *log* >&/dev/null; then echo "there are files of type log"; fi

You also can do it using only the shell, without even ls, though it's a bit wordier:

for f in *log*; do 
  # even if there are no matching files, the body of this loop will run once
  # with $f set to the literal string "*log*", so make sure there's really
  # a file there:
  if [ -e "$f" ]; then 
    echo "there are files of type log"
    break
  fi
done 

As long as you're using bash specifically, you can set the nullglob option to simplify that somewhat:

shopt -s nullglob
for f in *log*; do
  echo "There are files of type log"
  break
done
like image 176
Mark Reed Avatar answered Sep 17 '22 12:09

Mark Reed


Or without if; then; fi:

ls | grep -q log && echo 'there are files of type log'

Or even:

ls *log* &>/dev/null && echo 'there are files of type log'
like image 24
Alex Avatar answered Sep 17 '22 12:09

Alex