2012-05-14 4 views
19

Я пишу очень простые сценарии оболочки, которые будут смотреть на журнал всех неудавшихся тестов и распечатывать все имена всех файлов в текущем каталоге, которые находятся в журналеПроверьте вывод команды в сценарии оболочки

1 #! /bin/sh 

2 for file in * 
3 do 
4  echo "checking: $file" 
5  if [$(grep $file failed.txt -c) -ne 0] 
6  then 
7   echo "$file FAILED" 
8  fi 
9 done 

Когда я исполню его, я получаю эту ошибку:

line 6: [0: command not found 

кто-нибудь есть какие-либо идеи, почему?

Спасибо!

+0

Вы хотите переместить - ne в начало if-statement – keyser

+4

вам не хватает пробела: '' if [$ (grep $ fi le failed.txt -c) -ne 0] '' – redShadow

ответ

25

[ - фактически команда в linux (например, bash или cat или grep).

$(grep $file failed.txt -c) является команда подстановки в вашем случае оценивается в 0. Таким образом, линия в настоящее время читает [0 -ne 0], который интерпретируется как запустить программу под названием [0 с аргументами -ne 0].

Вместо этого вы должны написать [ $(grep $file failed.txt -c) -ne 0 ]. Сценарии оболочки требуют, чтобы между открывающимися и закрывающимися квадратными скобками были пробелы. В противном случае вы измените команду, которая выполняется (закрытие ] указывает на то, что больше нет аргументов, чтобы быть считаны.

Так что теперь команда вычисляет [ 0 -ne 0 ]. Вы можете попробовать выполнения этого в вашей оболочке, чтобы увидеть, что происходит. [ выходы со значением 0, если выражение истинно и 1, если оно ложно. вы можете увидеть значение выхода на вторя $? (значение выхода последней команды, которая будет работать).

+0

Вы все равно должны избегать бесполезного использования обратных ссылок. http://partmaps.org/era/unix/award.html#backticks (обратите особое внимание на отдельный пример). – tripleee

+0

@ tripleee Хороший совет, но я бы не сказал особенно актуальным в этом случае, поскольку вывод grep в этом случае, вероятно, будет крошечным по сравнению с ARG_LIMIT. Хотя, как заметил кто-то в другом комментарии, 'если grep $ file failed.txt -q' является идеальным решением. Я вообще не заинтересован в использовании перенаправления вывода, так как они упрощают чтение скриптов (больше токенов для чтения и обработки). – Dunes

+0

О, абсолютно; 'if grep -q' то, что я получаю, тоже. (Кажется, у вас есть шаблон поиска, и аргумент файла изменился?) – tripleee

6

Вместо проверки счетчика, вы может проверить код возврата grep:

if grep -q $file failed.txt &>/dev/null 
+0

Ну, вы всегда можете выделить одну строку и весь скрипт. 'cat не удалось.txt | xargs ls -f1 2>/dev/null' – Dunes

+3

Вы получаете немного эффективности, используя 'grep -q' - если есть совпадение, grep немедленно выходит. –

+1

Обратите внимание, что перенаправление '&>' не posix. Bash будет интерпретировать его так же, как '>/dev/null 2> & 1', но не все оболочки будут. (например, тире будет вызывать grep в фоновом режиме и усекать/dev/null) –

1

Сценарий может быть

#!/bin/sh 

for file in *; do 
    echo "checking: $file" 
    grep failed.txt $file && echo "$file FAILED" 
done 

или, как однострочника в пользовательской истории командной оболочки:

for file in *; do { echo "checking: $file" && grep failed.txt $file && echo "$file FAILED"; done

в man grep

EXIT STATUS
The exit status is 0 if selected lines are found, and 1 if not found. If an error occurred the exit status is 2. (Note: POSIX error handling code should check for '2' or greater.)

Смежные вопросы