Що робить
echo $?
означає в програмуванні оболонок?
Що робить
echo $?
означає в програмуванні оболонок?
Відповіді:
Це статус виходу останньої виконаної команди.
Наприклад, команда true
завжди повертає статус 0
і false
завжди повертає статус 1
:
true
echo $? # echoes 0
false
echo $? # echoes 1
З посібника: (доступно, зателефонувавши man bash
до вашої оболонки)
$?
Розширюється до статусу виходу останнього виконаного переднього плану трубопроводу.
За умовою статус виходу 0
означає успіх, а ненульовий стан повернення означає збій. Дізнайтеся більше про статуси виходу на wikipedia .
Існують і інші спеціальні змінні, як це, як ви бачите в цьому онлайн-посібнику: https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
$
і ?
є двома різними параметрами , і $?
не з'являється в БАШЕЄВ (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 ]
пізніше.
ехо $? - Дає EXIT STATUS останньо виконаної команди . Цей ВИХІДНИЙ СТАТУС, швидше за все, буде числом, при якому ZERO передбачає Успіх і будь-яке значення НЕ-ЗЕРО, що вказує на невдачу
? - Це один спеціальний параметр / змінна в bash.
$? - Це дає значення, збережене у змінній "?".
Деякі подібні спеціальні параметри в BASH - 1,2, *, # (зазвичай в команді echo сприймаються як $ 1, $ 2, $ *, $ # тощо).
Він має останній код стану (значення виходу) команди.
Приклад мінімального POSIX C виходу
Щоб зрозуміти $?
, спочатку слід зрозуміти концепцію стану виходу з процесу, яка визначена POSIX . У Linux:
коли процес викликає exit
системний виклик, ядро зберігає значення, передане системному виклику (an 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, fork + exec + wait відбувається, як вище, і bash потім встановлює $?
статус виходу з forked процесу.
Примітка. Для таких вбудованих команд 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 Спеціальні параметри :
? - Розширює стан виходу останнього виконаного переднього плану трубопроводу.
Її трохи важко знайти, оскільки вона не вказана як $?
(назва змінної - "просто" ?
). Також, дивіться розділ стану виходу ; звичайно;
Щасливе кодування.