Что значит
echo $?
значит в программировании оболочки?
Что значит
echo $?
значит в программировании оболочки?
Ответы:
Это статус выхода последней выполненной команды.
Например, команда true
всегда возвращает статус 0
и false
всегда возвращает статус 1
:
true
echo $? # echoes 0
false
echo $? # echoes 1
Из руководства: (доступно через вызов man bash
в вашей оболочке)
$?
Расширяется до состояния выхода последнего выполненного переднего конвейера.
По соглашению статус выхода 0
означает успех, а ненулевой статус возврата означает сбой. Узнайте больше о статусах выхода в Википедии .
Есть и другие специальные переменные, подобные этой, как вы можете видеть в этом онлайн-руководстве: https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
$
и ?
это два разных параметра $?
, которые не отображаются на странице руководства bash (1).
$?
возвращает значение выхода последней выполненной команды. echo $?
выводит это значение на консоль Ноль подразумевает успешное выполнение, в то время как ненулевые значения отображаются на различные причины сбоя.
Следовательно, при написании сценариев; Я склонен использовать следующий синтаксис
if [ $? -eq 0 ]; then
# do something
else
# do something else
fi
Сравнение должно быть сделано на равных 0
или не равных 0
.
** Обновление на основе комментария: в идеале, вы не должны использовать вышеуказанный блок кода для сравнения, обратитесь к комментариям и объяснениям @tripleee.
cmd; if [ $? -eq 0 ]; then
должно быть подвергнуто рефакторингу if cmd; then
. Сама цель из if
(и другие операторы управления потоком в оболочке), чтобы выполнить команду и проверьте его состояние выхода.
if cmd;
Некоторые условия могут быть не очень читабельными, особенно когда cmd ссылается на другой скрипт.
[ 1 ]
и [ 0 ]
оба верны; [
без оператора проверяет, является ли аргумент непустой строкой.
vendor/bin/drush status bootstrap | grep -q $(vendor/bin/drush php-eval 'if (function_exists("t")) echo t("Successful");') &> /dev/null;
. Если бы мне пришлось поместить это в одну строку, if [ ... ]
это было бы ужасно нечитаемо. Я планирую сохранить вывод этой строки в переменной, так что я могу сказать if [ $drupal_installed -eq 0 ]
позже.
echo $? - Дает СТАТУС ВЫХОДА последней выполненной команды . Это СОСТОЯНИЕ ВЫХОДА, скорее всего, будет числом с НУЛЕМ, означающим Успех, и любым НУЛЕВОЙ величиной, указывающей Отказ
? - Это один специальный параметр / переменная в bash.
$? - Это дает значение, хранящееся в переменной «?».
Некоторые аналогичные специальные параметры в BASH: 1,2, *, # (обычно в команде echo видны как $ 1, $ 2, $ *, $ # и т. Д.,).
У него есть последний код состояния (значение выхода) команды.
Пример минимального состояния выхода POSIX C
Чтобы понять $?
, вы должны сначала понять концепцию статуса выхода процесса, которая определяется POSIX . В Linux:
когда процесс вызывает exit
системный вызов, ядро сохраняет значение, переданное системному вызову (int
), даже после того, как процесс умирает.
Системный вызов выхода вызывается exit()
функцией ANSI C, и косвенно, когда вы делаете return
из main
.
процесс, который вызвал выходящий дочерний процесс (Bash), часто с fork
+ exec
, может получить статус выхода дочернего процесса с помощью wait
системного вызова
Рассмотрим код Bash:
$ false
$ echo $?
1
C «эквивалент» это:
false.c
#include <stdlib.h> /* exit */
int main(void) {
exit(1);
}
bash.c
#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */
int main(void) {
if (fork() == 0) {
/* Call false. */
execl("./false", "./false", (char *)NULL);
}
int status;
/* Wait for a child to finish. */
wait(&status);
/* Status encodes multiple fields,
* we need WEXITSTATUS to get the exit status:
* http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
**/
printf("$? = %d\n", WEXITSTATUS(status));
}
Скомпилируйте и запустите:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o bash bash.c
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o false false.c
./bash
Вывод:
$? = 1
В Bash, когда вы нажимаете Enter, происходит форк + exec + wait, как описано выше, а затем bash устанавливает $?
состояние завершения разветвленного процесса.
Примечание: для встроенных команд, таких как echo
, процесс не нужно запускать, а Bash просто устанавливает$?
0 для имитации внешнего процесса.
Стандарты и документация
POSIX 7 2.5.2 «Специальные параметры» http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :
? Расширяется до десятичного состояния выхода самого последнего конвейера (см. Конвейеры).
man bash
«Специальные параметры»:
Оболочка обрабатывает несколько параметров специально. На эти параметры можно ссылаться только; присвоение им не допускается. [...]
? Расширяется до состояния выхода последнего выполненного переднего конвейера.
Затем ANSI C и POSIX рекомендуют:
0
означает, что программа была успешной
другие значения: программа как-то не удалась.
Точное значение может указывать тип отказа.
ANSI C не определяет значение каких-либо значений, а POSIX определяет значения больше 125: что означает «POSIX»?
Bash использует статус выхода для if
В Bash мы часто $?
неявно используем статус выхода для управления if
операторами, как в:
if true; then
:
fi
где true
программа, которая просто возвращает 0.
Вышеуказанное эквивалентно:
true
result=$?
if [ $result = 0 ]; then
:
fi
И в:
if [ 1 = 1 ]; then
:
fi
[
это просто программа со странным именем (и встроенной в Bash, которая ведет себя так же, как она) и 1 = 1 ]
ее аргументами, см. также: Разница между одинарными и двойными квадратными скобками в Bash
С http://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
?
Expands to the exit status of the most recently executed foreground pipeline.
См . Руководство по Bash в разделе 3.4.2. Специальные параметры :
? - Расширяется до состояния выхода последнего выполненного переднего конвейера.
Это немного сложно найти, потому что он не указан как $?
(имя переменной «просто» ?
). Также смотрите раздел статуса выхода , конечно ;-)
Удачного кодирования.