Я хочу установить возвращаемое значение один раз, чтобы оно перешло в цикл while:
#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0
done
Чтобы получить эту работу, мне нужно установить $? = 1
в начале, но это не сработает.
Я хочу установить возвращаемое значение один раз, чтобы оно перешло в цикл while:
#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0
done
Чтобы получить эту работу, мне нужно установить $? = 1
в начале, но это не сработает.
#!/bin/bash
RC=1
while [ $RC -eq 1 ]
do
#do something until it returns 0
RC=$?
done
Вы можете установить произвольный код выхода, выполнив 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
не будет выполнена.
false
всегда возвращает код выхода из 1.
#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0
done
Некоторые ответы полагаются на переписывание кода. В некоторых случаях это может быть внешний код, который вы не контролируете.
Хотя для этого конкретного вопроса достаточно установить $? до 1, но если вам нужно установить $? на любую ценность - единственный полезный ответ - вопрос от Денниса Уильямсона.
Немного более эффективный подход, который не порождает нового ребенка (но также является менее кратким):
function false() { echo "$$"; return ${1:-1}; }
false 42
Примечание. Часть эха должна просто проверить, работает ли она в текущем процессе.
Я думаю, вы можете сделать это неявно, выполнив команду, которая, как гарантируется, завершится неудачно, перед входом в цикл while
.
Каноническая такая команда, конечно, false
.
Не нашел ничего более легкого, чем простая функция:
function set_return() { return ${1:-0}; }
Все другие решения, такие как (...)
или [...]
или false
, могут содержать внешний вызов процесса.
Будет ли что-то вроде этого быть тем, что вы ищете?
#!/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
Старый вопрос, но есть гораздо лучший ответ:
#!/bin/bash
until
#do something until it returns success
do
:;
done
Если вы зацикливаетесь до тех пор, пока что-то не будет успешным, тогда просто сделайте что-нибудь в разделе до тех пор, пока не будет. Вы можете поместить точно такой же код в раздел до тех пор, пока вы не подумали, что вам нужно вставить раздел do/done. Вы не обязаны писать код в разделе do/done, а затем передавать его результаты обратно или пока.
Вы можете использовать until
для обработки случаев, когда #do something until it returns 0
возвращает что-то, отличное от 1 или 0:
#!/bin/bash
false
until [ $? -eq 0 ]
do
#do something until it returns 0
done