Sandra Schlichting
Sandra Schlichting

Reputation: 25986

Possible to pipe into an if-statement?

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?

Upvotes: 20

Views: 43101

Answers (8)

mah454
mah454

Reputation: 1919

I have a simple example for pipe to statement without if keyword :

echo -e hello | [ $(cat) == hello ] && echo "Ok"

with else too easy :

echo -e hello | ([ $(cat) == 'bye' ] && echo "Ok" || echo "No Okey")

For example you want to check status code of http response is equal to 200 or not :

curl http://google.com -w "%{http_code}" -s -o /dev/null | [ $(cat) == 200 ] && echo "Request successful processed"
# Note: in this example google response is 403 .

Upvotes: 2

JMirabile
JMirabile

Reputation: 11

How about the following:

#!/bin/bash

if [ -z $1 ]; then
   echo Usage: $0 [UID to search for]
   exit 1;
fi

SEARCHID="$1"

function notFound() {
    echo NOT FOUND 
}

function found() {
    echo Found it
}

function main() {

    grep -i $SEARCHID /etc/passwd
    # Move $? to a variable 
    SEARCHRESULT=$?

    if [ "$SEARCHRESULT" != "0" ]; then
       notFound;
    else
       found;
    fi
}

# call main function
main

Upvotes: 1

user1789538
user1789538

Reputation: 163

Just use &&:

grep -q root /etc/password && echo "root is found"

grep -q nobody /etc/password && echo "nobody is found"

Upvotes: 1

tripleee
tripleee

Reputation: 189367

In the general case, you could use a temporary file.

t=$(mktemp -t passwd.XXXXXXXX)
trap 'rm $t' 0
trap 'exit 127' 1 2 3 5 15
cat >$t
for u in root nobody; do
  fgrep $u $t
done

The traps are to remove the temporary file afterwards.

As an aside, you can pipe to an if, but the first grepinside your conditional would already consume all of its standard input. It's more useful in situations like this:

if $option_count ; then
    wc -l
else
    tac
fi <file

Upvotes: 0

sorpigal
sorpigal

Reputation: 26086

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.

Upvotes: 9

Michał Kosmulski
Michał Kosmulski

Reputation: 10020

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.

Upvotes: 5

Benoit
Benoit

Reputation: 79175

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.

Upvotes: 4

Fred Foo
Fred Foo

Reputation: 363547

Piping into an if-statement is possible with subshells, but that solution will break since you're running two grep commands on the pipe, the first of which will exhaust it.

The best solution in your case is probably to read /etc/passwd into a variable, then grep it:

passwd=$(cat /etc/passwd)
if (echo $passwd | grep -q root); then
     echo "root found"
fi
if (echo $passwd | grep -q nobody); then
     echo "nobody found"
fi

Upvotes: 3

Related Questions