Я пытаюсь изучить shell-скрипты, и мне нужно понять код другого. Что удерживает переменную $?
? Я не могу выполнить поиск Google, потому что они блокируют знаки пунктуации.
Что такое $? (знак вопроса доллара) в сценариях оболочки?
Ответ 1
$?
используется для поиска возвращаемого значения последней выполненной команды.
Попробуйте следующее в оболочке:
ls somefile
echo $?
Если somefile
существует (независимо от того, является ли это файлом или каталогом), вы получите возвращаемое значение, созданное командой ls
, которая должна быть 0
(значение по умолчанию "success" ). Если он не существует, вы должны получить число другое, то 0. Точное число зависит от программы.
Для многих программ вы можете найти числа и их значение на соответствующей странице руководства. Они обычно описываются как "статус выхода" и могут иметь свой раздел.
Ответ 2
Это статус выхода последней выполненной функции/программы/команды. См. Также:
Ответ 3
Возвращаемое значение ранее выполненного процесса.
10.4 Получение возвращаемого значения программы
В bash возвращаемое значение программы сохраняется в специальной переменной называется $?.
Это иллюстрирует, как фиксировать возвращаемое значение программы, я предположим, что каталог dada не существует. (Это было также предложенный майком)
#!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $?
Подробнее см. Bash Руководство по программированию.
Ответ 4
Пример минимального состояния выхода POSIX C
Чтобы понять $?
, вы должны сначала понять концепцию статуса завершения процесса.
В Linux:
когда процесс вызывает системный вызов
exit
, ядро сохраняет значение, переданное системному вызову, даже после того, как процесс умирает.Системный вызов выхода вызывается функцией ANSI C
exit()
и косвенно, когда вы делаетеreturn
изmain
.процесс, который вызвал выходящий дочерний процесс (Bash), часто с помощью
fork
+exec
, может получить состояние завершения дочернего процесса с помощью системного вызоваwait
Рассмотрим код Bash:
$ false
$ echo $?
1
C "эквивалент":
false.c:
#include <stdlib.h> /* exit */
int main() {
exit(1);
}
bash.c:
#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */
int main() {
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));
}
В 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
Ответ 5
$? это результат (код выхода) последней выполненной команды.
Ответ 6
Это возвращаемый код ошибки последней выполненной команды. 0 = успех
Ответ 7
$?
- это статус выхода команды, так что вы можете последовательно генерировать последовательность команд.
Пример
command1 && command2 && command3
command2
будет выполняться, если command1's
$?
дает success (0)
и command3
будет выполняться, если $?
of command2
даст success
Ответ 8
Вышел код выхода последней команды.
Ответ 9
Он хорошо подходит для отладки в случае выхода из скрипта, если используется set -e
. Например, поместите echo $?
после команды, которая заставляет его выйти и увидеть возвращаемое значение ошибки.