Як запустити команду і отримати її вихідний код меншою кількістю символів?


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

Це виглядає краще, ніж моє, хоча це однолінійний ;-)
Антон

ОП може захотіти розділити його на кілька рядків, якщо йому потрібно буде виконати кілька команд після відмови :)
Джон У. Сміт

Немає причин, чому ви не можете переламати його на півколони, щоб зробити його багаторядковим.
Марк Стюарт

1
... або пишітьwhile ! some_command; do several; commands; sleep 1; done
ignis

12

Це те, що untilцикл призначений для:

until some_command
do    sleep 1
done

Це логічне заперечення whileциклу.

Специфікація каже:

untilLoop

  • untilЦикл повинен безперервно виконати одну з'єднання-список тих пір , поки інше з'єднання-лист має статус виходу ненульовий.

  • Формат циклу до:

    до складання списку-1
    зробити складений список-2
    зроблено
  • З'єднання-лист-1 повинен бути виконаний, і якщо він має статус нульового виходу, то untilкоманда виконається. В іншому випадку склад-список-2 повинен бути виконаний, і процес повторюється.

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);

(Як зазначено вище, команда sleepis виконується лише у випадку відмови команди.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.