2016-04-02 2 views
3

Я пытаюсь автоматизировать нашу резервную копию приложения. Часть всего кода является оператором if с условием ИЛИ, которое бросает ошибку - [: too many arguments. Ниже приведен оператор if.bash - if statement - [: слишком много аргументов

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] || 
    [ egrep -i -q "error|warning|fatal|missing|critical" "$File" ] 
then 
    echo "testing" 
fi 
-bash: [: too many arguments 

Я пробовал использовать все виды синтаксиса - дополнительные скобки, цитаты и т. Д., Но ошибка по-прежнему сохраняется.

Пожалуйста, помогите мне понять, в чем я ошибаюсь.

+0

', если команда ....' –

+0

@DavidGrayson: это вовсе не означает, что его "работает". –

+0

'egrep' не должен быть окружен скобками. – kichik

ответ

6

Вы делаете общую ошибку, считая, что [ является частью синтаксиса инструкции if. Это не; Синтаксис if просто

if command; then 
    ... things which should happen if command's result code was 0 
else 
    ... things which should happen otherwise 
fi 

Одна из общих command с мы используем [, который является псевдонимом для команды test. Это простая команда для сравнения строк, чисел и файлов. Он принимает довольно узкую комбинацию аргументов и, как правило, создает путаные и вводящие в заблуждение сообщения об ошибках, если вы не передадите ему ожидаемые аргументы. (Или, скорее, сообщения об ошибках адекватны и полезны, как только вы привыкнете к нему, но они легко поняли, если вы не привыкли.)

Здесь вы хотите проверить результат команды egrep:

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] || 
    egrep -i -q "error|warning|fatal|missing|critical" "$File" 
then 
    echo "testing" 
fi 

В общем случае command может быть конвейером или списком команд; то код завершения из конечной команды - это состояние, которое будет изучать if, подобно тому, как последняя команда в скрипте определяет статус выхода из сценария.

Этих составных команд может быть сколь угодно сложным, как

if read thing 
    case $thing in 
     '' | 'quit') false;; 
     *) true;; 
    esac 
then ... 

, но на практике редко можно увидеть более чем одной команды в if заявлении (хотя это не неслыханное, ваше соединение заявление с || является хороший пример!)

Исторические причины для test как общая кухонная раковина материала авторы не хотели составлять часть синтаксиса if - один из менее привлекательных дизайнов оригинальной раковины Борна. Bash и zsh предлагают альтернативы, которые менее громоздки (например, [[ двойные скобки в bash), и, конечно же, POSIX test намного более вспыльчивый, чем оригинальное создание Bell Labs.

+0

Это адаптация [этого более раннего моего ответа] (http://stackoverflow.com/a/10586252/874188) к смутно подобранному вопросу. – tripleee

+1

Nit pick: синтаксис 'if' на самом деле' если список команд; then', а последняя команда определяет статус. И * команда * может быть трубой. – Jens

+0

@Jens Спасибо, очень проницательный!Обновлено. – tripleee

-4

Это работает: поставить в задать расширенное "$()", удалить -q и сделать сравнение строк:

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] || 
    [ "$(egrep -i 'error|warning|fatal|missing|critical' $File)" != "" ]; 
then 

    echo "testing"; 

fi 
+0

Примечание: не будет работать, если $ File содержит пробелы ... bash дает мне головные боли! Как поместить двойные кавычки в двойные кавычки! – Baptiste

+3

Downvote: пожалуйста, не размножайте антипаттерн [бесполезных backticks] (http://www.iki.fi/era/unix/award.html#backticks) – tripleee

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