Можно ли подключиться к 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