2013-08-19 3 views
12

В bash я хочу сказать «если файл не содержит XYZ, а затем« сделайте кучу вещей ». Самый естественный способ перенести это в код что-то вроде:Bash условно на код выхода команды

if [ ! grep --quiet XYZ "$MyFile" ] ; then 
    ... do things ... 
fi 

Но, конечно, это не действительный синтаксис Bash. Я мог бы использовать backticks, но тогда я буду тестировать вывод файла. Две альтернативы, я могу думать о том, являются:

grep --quiet XYZ "$MyFile" 
if [ $? -ne 0 ]; then 
    ... do things ... 
fi 

И

grep --quiet XYZ "$MyFile" || 
    ( ... do things ... 
    ) 

I рода предпочитают второй один, это более Lispy и || для потока управления не так уж и необычен в языках сценариев. Я тоже вижу аргументы для первого, хотя, когда человек читает первую строчку, они не знают , почему вы выполняете grep, похоже, что вы выполняете его для основного эффекта, а не только для управлять ветвью в скрипте.

Есть ли третий, более прямой способ, который использует оператор if и имеет grep в состоянии?

+0

возможно дубликат [встреча «ожидается унарный оператор» в Баш скрипт] (http://stackoverflow.com/questions/10586213/encounter-unary-operator-expected-in-bash-script) – tripleee

ответ

20

Да есть:

if grep --quiet ..... 
then 
    # If grep finds something 
fi 

или если Grep не удается

if ! grep --quiet ..... 
then 
    # If grep doesn't find something 
fi 
+0

D'oh! Благодарю. В моей защите я не видел этого в каких-либо учебниках, даже тех, которые говорят о проверке кода выхода команды. –

+1

'[' является своего рода псевдонимом для 'test' (что также требует') '). Поэтому 'if [...]' эквивалентно 'if test ...' – coldfix

+0

Что делать, если вы хотите протестировать несколько условий, одним из которых является статус выхода команды? Как в: 'if [[$ OS ==" windows "&& command-exit-status == 0]]; ...' ? Я могу запустить команду сначала и сохранить '$?', Конечно, но мне бы хотелось, чтобы команда «&&» использовалась так, чтобы она не запускала команду, кроме '$ OS == windows'. Любые хорошие идеи? – GaryO

2

Это дело вкуса, так как, очевидно, несколько рабочих решений. Когда я сталкиваюсь с такой проблемой, я обычно применяю wc -l после grep, чтобы подсчитать линии, которые соответствуют. Затем у вас есть одно целое число, которое вы можете оценить в рамках условия теста. Если вопрос только есть ли матч вообще (число совпадающих строк не имеет значения), то, применяя wc, вероятно, OTT и оценка коды возврата grep «s, кажется, лучшее решение:

Обычно статус выхода равен 0, если выбранные линии найдены и 1 в противном случае. Но статус выхода равен 2, если произошла ошибка, если не используется опция -q или --quiet или --silent и выбрана выбранная строка. Обратите внимание, однако, что POSIX требует только для таких программ, как grep, cmp и diff, что статус выхода в случае ошибки будет больше 1; поэтому желательно, ради портативности, чтобы использовать логики, которая проверяет для этого общего состояния вместо строгого равенства с 2.

7

Вам не нужно [] (test), чтобы проверить возвращение значение команды. Просто попробуйте:

if ! grep --quiet XYZ "$MyFile" ; then 
Смежные вопросы