Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to pipe into an if-statement?

Tags:

linux

bash

I have a script that outputs about 10 lines every time if it run. The content of these lines varies.

I would really like to be able to grep in the output and do different things depending on the output.

In pseudo this is what I would like to do

cat /etc/password | \\
if [ grep "root" $STDOUT ]; then
   echo "root is found"

elif [ grep "nobody" $STDOUT ]; then
   echo "nobody is found"

fi

Here have I used cat /etc/password as an example, but it should be replaced with my scripts mentioned above.

The problem is, how do I get hold of the output from cat /etc/password in the if/elif conditions?

like image 463
Sandra Schlichting Avatar asked Feb 24 '12 10:02

Sandra Schlichting


People also ask

How many commands can you pipe together?

The pipe takes output from one command and uses it as input for another. And, you're not limited to a single piped command—you can stack them as many times as you like, or until you run out of output or file descriptors.

What is if in scripting?

The if statement is composed of the if keyword, the conditional phrase, and the then keyword. The fi keyword is used at the end of the statement. The COMMANDS gets executed if the CONDITION evaluates to True. Nothing happens if CONDITION returns False; the COMMANDS are ignored.

What is pipe in bash?

A pipe in Bash takes the standard output of one process and passes it as standard input into another process. Bash scripts support positional arguments that can be passed in at the command line.


3 Answers

You just do :

if grep -q "root" /etc/passwd ; then
   ...
fi

which will play the ... commands if grep exit code is 0.

remember that \[ is a external command, probably located in /usr/bin/[ (normally it's a hard link to test and when invoked as [ it requires a matching ] argument). Also see the pitfalls page here, many of them deal are related to that command.

like image 142
Benoit Avatar answered Oct 18 '22 20:10

Benoit


I'd suggest using awk:

cat /etc/passwd | awk '/root/{ do something }/nobody/{ do something else }'

You can achieve the same in bash using an expression like:

cat /etc/passwd |
while read; do
  if echo "$REPLY" | fgrep root; then
    something
  fi
  if echo "$REPLY" | fgrep nobody; then
    something_else
  fi
done

However the pure bash solution is less efficient for large inputs because it runs separate instances of grep for every line.

like image 32
Michał Kosmulski Avatar answered Oct 18 '22 22:10

Michał Kosmulski


As @Benoit recommends, just use grep directly.

As @larsmans notes, you can avoid a double-read of the file by reading it into a variable once.

Given the availability of bash I'd do it like this:

password=$(< /etc/passwd)

if grep -q root <<< "$password" ; then
    echo root found
elif grep -q nobody <<< "$password" ; then
    echo nobody found
fi

One read of the file, one or two invocations of grep, no other processes or subshells launched.

like image 9
sorpigal Avatar answered Oct 18 '22 20:10

sorpigal