Можно ли подключиться к if-заявлению?

У меня есть script, который выдает около 10 строк каждый раз, если он запускается. Содержание этих строк меняется.

Мне бы очень хотелось иметь возможность grep в выходе и делать разные вещи в зависимости от выхода.

В псевдо это то, что я хотел бы сделать

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

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

fi

Здесь я использовал cat /etc/password в качестве примера, но его нужно заменить на мои сценарии, упомянутые выше.

Проблема в том, как я могу получить вывод из cat /etc/password в условиях if/elif?

Ответ 1

Как рекомендует @Benoit, просто используйте grep напрямую.

Как отмечает @larsmans, вы можете избежать двойного чтения файла, просто прочитав его в переменной.

Учитывая наличие bash, я сделал бы это так:

password=$(< /etc/passwd)

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

Одно чтение файла, одно или два вызова grep, никаких других процессов или подоболочек не запущено.

Ответ 2

Вы просто выполните:

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

который будет воспроизводить команды ..., если код выхода grep равен 0.

помните, что \[ является внешней командой, вероятно, расположенной в /usr/bin/[ (обычно это жесткая ссылка на test и когда вызывается как [ для этого требуется соответствующий аргумент ]). Также см. Страницу pitfalls здесь, многие из них связаны с этой командой.

Ответ 3

Я бы предложил использовать awk:

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

Вы можете добиться того же результата в bash, используя выражение типа:

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

Однако чистое решение bash менее эффективно для больших входов, потому что оно запускает отдельные экземпляры grep для каждой строки.

Ответ 4

Трубопровод в if-statement возможен с подоболочками, но это решение сломается, так как вы выполняете две команды grep на трубе, первая из которых будет исчерпать его.

Лучшим решением в вашем случае является, вероятно, чтение /etc/passwd в переменную, а затем 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

Ответ 5

Просто используйте & &:

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

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

Ответ 6

В общем случае вы можете использовать временный файл.

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

После этого trap необходимо удалить временный файл.

В стороне вы можете перейти к if, но первая grep внутри вашего условного значения уже будет потреблять весь свой стандартный ввод. Это более полезно в таких ситуациях:

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

Ответ 7

Как насчет следующего:

#!/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