Що робить
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 Спеціальні параметри :
? - Розширює стан виходу останнього виконаного переднього плану трубопроводу.
Її трохи важко знайти, оскільки вона не вказана як $?(назва змінної - "просто" ?). Також, дивіться розділ стану виходу ; звичайно;
Щасливе кодування.