2016-01-16 2 views
0

У меня есть функция, которая, кажется, прерывается, когда я включаю ошибки с set -e. Я подозреваю, что он работает по назначению, но я не вижу, что я делаю неправильно.set -e делает функцию прекратить работать на ранней стадии?

Вот функция:

#!/usr/bin/env bash 

set -e 

my_function() { 
    base_dir="/tmp/test" 
    if [ ! -d $base_dir ]; then 
     echo "Creating $base_dir" 
     mkdir -p $base_dir 
     touch $base_dir/some-file.txt 
    fi 

    is_edited=$(grep "foo" $base_dir/some-file.txt) 

    if [ ! -z $is_edited ]; then 
     cd $base_dir 
     echo "Doing stuff" 
     docker run --rm debian ls 
    fi 

    echo 
    echo "Done" 
    echo 
} 

my_function 

С set -e переворачивается, функция возвращает, казалось бы, не ударил эхо заявления. При выключенном set -e вызывают атаки эха. Что происходит и как я могу это исправить?

+1

'grep' возвращает ненулевой код выхода, если он не находит соответствия. Это будет считаться ошибкой 'set -e'. – Barmar

+0

@ Бармар А, это имеет смысл. Может быть, есть лучший подход к этому, чем использование grep или есть лучший способ обработать возвращаемое значение для него? – jmreicha

ответ

3

Попробуйте использовать:

is_edited=$(grep "foo" $base_dir/some-file.txt || test $? -eq 1) 

Статус выхода grep является 0, если он нашел совпадение, 1, если он не нашел ни одного матча, и 2, если он получил фактическую ошибку. Поэтому, если в файле нет соответствия foo, это будет считаться ошибкой, и set -e прекратит выполнение скрипта. Вышеприведенный код переводит 1 на успех, поэтому скрипт будет завершен, только если grep получит реальную ошибку.

Если вы не заботитесь о прекращении сценария, если grep получает ошибку, вы можете просто использовать

if grep -1 "foo" $base_dir/some-file.txt ; then 
    ... 
fi 

Опция -q позволяет не печатать соответствующую строку, просто установить свой статус выхода на основе того, он нашел матч.

+0

Это работает. Кроме того, спасибо за объяснение. – jmreicha

1

как указано fmtn07, с кодом возврата.

попробуйте изменить заявление Grep от:

is_edited=$(grep "foo" $base_dir/some-file.txt)

к:

is_edited=$(grep "foo" $base_dir/some-file.txt || true)

+0

Это предотвратит прерывание сценария, если 'grep' действительно получит ошибку. – Barmar