Подтвердить что ты не робот

Как мне установить $? или код возврата в Bash?

Я хочу установить возвращаемое значение один раз, чтобы оно перешло в цикл while:

#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0    
done

Чтобы получить эту работу, мне нужно установить $? = 1 в начале, но это не сработает.

4b9b3361

Ответ 1

#!/bin/bash

RC=1

while [ $RC -eq 1 ]
do

  #do something until it returns 0    

  RC=$?
done

Ответ 2

Вы можете установить произвольный код выхода, выполнив exit с аргументом в подоболочке.

$ (exit 42); echo "$?"
42

Таким образом, вы можете сделать:

(exit 1)    # or some other value > 0 or use false as others have suggested
while (($?))
do
    # do something until it returns 0    
done

Или вы можете эмулировать цикл do while while:

while 
    # do some stuff
    # do some more stuff
    # do something until it returns 0    
do
    continue  # just let the body of the while be a no-op
done

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

Для полноты, exit и return каждый принимает необязательный аргумент, который является целым (положительным, отрицательным или нулевым), который устанавливает код возврата в качестве остатка целого числа после деления на 256. Текущая оболочка (или скрипт или подоболочка *) завершается используя exit и функция exit с использованием return.

Примеры:

$ (exit -2); echo "$?"
254
$ foo () { return 2000; }; foo; echo $?
208

* Это справедливо даже для подоболочек, которые создаются по трубам (за исключением случаев, когда оба управления заданиями отключены, а lastpipe включен):

$ echo foo | while read -r s; do echo "$s"; exit 333; done; echo "$?"
77

Обратите внимание, что лучше использовать break чтобы оставить циклы, но его аргумент состоит в том, что количество уровней циклов выходит из кода вместо кода возврата.

Управление заданием отключено с помощью set +m, set +o monitor или shopt -u -o monitor. Чтобы включить lastpipe сделайте shopt -s laspipe. Если вы оба из тех, то exit в предыдущем примере, приведет к тому, while цикл и содержащий оболочку для обоих выхода и окончательное echo не будет выполнена.

Ответ 3

false всегда возвращает код выхода из 1.

#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0    
done

Ответ 4

Некоторые ответы полагаются на переписывание кода. В некоторых случаях это может быть внешний код, который вы не контролируете.

Хотя для этого конкретного вопроса достаточно установить $? до 1, но если вам нужно установить $? на любую ценность - единственный полезный ответ - вопрос от Денниса Уильямсона.

Немного более эффективный подход, который не порождает нового ребенка (но также является менее кратким):

function false() { echo "$$"; return ${1:-1}; }
false 42

Примечание. Часть эха должна просто проверить, работает ли она в текущем процессе.

Ответ 5

Я думаю, вы можете сделать это неявно, выполнив команду, которая, как гарантируется, завершится неудачно, перед входом в цикл while.

Каноническая такая команда, конечно, false.

Ответ 6

Не нашел ничего более легкого, чем простая функция:

function set_return() { return ${1:-0}; }

Все другие решения, такие как (...) или [...] или false, могут содержать внешний вызов процесса.

Ответ 7

Будет ли что-то вроде этого быть тем, что вы ищете?

#!/bin/bash
TEMPVAR=1
while [ $TEMPVAR -eq 1 ]
do
  #do something until it returns 0
  #construct the logic which will cause TEMPVAR to be set 0 then check for it in the 
  #if statement 

  if [ yourcodehere ]; then
     $TEMPVAR=0
  fi
done

Ответ 8

Старый вопрос, но есть гораздо лучший ответ:

#!/bin/bash
until
    #do something until it returns success
do
    :;
done

Если вы зацикливаетесь до тех пор, пока что-то не будет успешным, тогда просто сделайте что-нибудь в разделе до тех пор, пока не будет. Вы можете поместить точно такой же код в раздел до тех пор, пока вы не подумали, что вам нужно вставить раздел do/done. Вы не обязаны писать код в разделе do/done, а затем передавать его результаты обратно или пока.

Ответ 9

Вы можете использовать until для обработки случаев, когда #do something until it returns 0 возвращает что-то, отличное от 1 или 0:

#!/bin/bash

false
until [ $? -eq 0 ]
do
#do something until it returns 0    
done