Как запустить команду и получить код ее выхода в меньшем количестве символов?

13

Я писал свои сценарии так:

some_command
while [ $? -ne 0 ] ; do
    sleep 1
    some_command
done

Меня всегда раздражало, что я должен писать some_commandдважды. Могу ли я как-то поместить его в секцию проверки петли?

Михай
источник

Ответы:

20

Вы можете использовать в some_commandкачестве вашего условия тестирования.

while ! some_command; do sleep 1; done

Условие будет оставаться верным до тех пор, пока some_commandвыходит с ошибкой.

Или более подробный способ, если вы хотите сделать дополнительные проверки:

while ! some_command
do 
    # add more if desired
    sleep 1
done
Джон У. Смит
источник
Это выглядит лучше, чем у меня, хотя это однострочник ;-)
Anthon
ОП, возможно, захочет разбить его на несколько строк, если ему потребуется выполнить несколько команд при неудаче, хотя :)
Джон В. У. Смит
Нет причин, по которым вы не можете разбить строку на точку с запятой, чтобы сделать ее многострочной.
Марк Стюарт
1
... или напишиwhile ! some_command; do several; commands; sleep 1; done
игнис
12

Вот для чего предназначен untilцикл:

until some_command
do    sleep 1
done

Это логическое отрицание whileцикла.

В спецификации сказано:

untilLoop

  • untilЦикл должен непрерывно выполнить одно соединение-список тех пор , пока другое соединение-лист имеет статус выхода ненулевой.

  • Формат цикла до следующего:

    до составного списка-1
    составить список-2
    сделано
  • Соединение-лист-1 должен быть выполнен, и если он имеет статус нулевого выхода, то untilкоманда выполнится. В противном случае составной список-2 должен быть выполнен, и процесс повторяется.
mikeserv
источник
4

Вы можете просто сделать:

false
while [ $? -ne 0 ] ; do
   sleep 1
   some_command
done

у этого есть недостаток, хотя это то, что это всегда спит одну секунду сначала

Если вы хотите иметь возможность выйти по любой из нескольких команд, чтобы выйти с 0, вы можете сделать:

while true; do
  if [ some_command ] ; then break ; fi
  if [ some_other_command ] ; then break ; fi
  sleep 1
done

что, конечно, также работает только для some_command

Энтон
источник
5
Второй пример не должен включать [и ]вокруг команд.
nyuszika7h
2

Ни работает, while ! ...ни until ...работает в системах, которые заморозили среду оболочки до POSIX.1-2001. Это, однако, делает.

while :; do
    if some command; then
        break
    fi
    sleep 1
done

Если вам не нужна полная переносимость, зачем вы пишете сценарий оболочки? Perl более доступен, чем Bash.

sleep 1 while 0 != system qw(some command);

(Как и выше, команда sleepвыполняется только в случае сбоя команды.)

zwol
источник