Що означає `{{(вихід 1); вихід 1; }; } `означає?


28

Я цитував наступний фрагмент коду, config.statusстворений користувачем configure.

if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi

У фрагменті коду, що { (exit 1); exit 1; };робити? Яка мета лише робити exitв підкашрі?

Відповіді:


33

Виконання (exit 1);- найпростіший спосіб спрацювання ERRпастки. Це також спровокує негайний вихід, якщо set -eдіє. (Ініціювання умови помилки вимагає відмови команди; exitпри значенні відмови в підпакеті призводить до відмови підкашля.)

exit 1; не зробить жодної з цих речей.

Таким чином, {(exit 1); exit 1;}можна використовувати спочатку виробити ERRпастку, яка може зробити щось корисне для налагодження, а потім припинити сценарій із вказівкою на помилку.

Але це не те, що відбувається у autoconfфайлах. autoconfсценарії покладаються на EXITпастку, щоб очистити тимчасові файли, створені під час виконання. Більшість оболонок, у тому числі bashвстановлюють статус із значення, яке надається в exitкоманді, перед тим, як викликати EXITпастку. Це могло б дозволити EXITпастці виявити, чи викликано її помилкою чи нормальним припиненням, а також дозволяє переконатися, що стан виходу правильно встановлено в кінці операції пастки.

Однак, мабуть, деякі снаряди не співпрацюють. Ось цитата з autoconfпосібника :

Деякі скрипти оболонки, наприклад, створені користувачем autoconf, використовують пастку для очищення перед виходом. Якщо остання команда оболонки вийшла з ненульового статусу, пастка також виходить із ненульовим статусом, щоб виклик міг повідомити, що сталася помилка.

На жаль, у деяких оболонках, таких як Solaris /bin/sh, пастка виходу ігнорує аргумент команди exit. У цих оболонках пастка не може визначити, чи викликано її простим виходом чи виходом 1. Замість виклику виходу безпосередньо використовуйте AC_MSG_ERRORмакрос, який має вирішення для цієї проблеми.

Вирішення завдання полягає в тому, щоб переконатися, що він $?має статус виходу перед виконанням exitкоманди, так що воно обов'язково матиме це значення при виконанні EXITпастки. І справді, саме AC_MSG_ERRORмакрос вводить цей цікавий код, доповнений зайвими дужками.


Чому б просто не виконати falseзамість цього (exit 1)?
Руслан

3
@ Руслан: Дві проблеми. (1) Найголовніше: falseне дозволяє встановлювати код статусу і немає гарантії того, який ненульовий статус він повертає. (2) falseзазвичай не є вбудованим, тому він вимагає дочірнього процесу; на відміну від цього, більшість снарядів може уникнути нересту дитини, який обробляє (exit 1).
rici

8

Наскільки я бачу, для цього немає ніякої мети, немає нічого, чого можна досягти безпосередньо, запустивши нижню частину оболонки та негайно вийшовши з неї.

Такі речі, швидше за все, є побічним ефектом автоматичного генерування коду - у деяких випадках можуть бути й інші команди, виконані в підпакеті, де це exit 1має сенс. Зрештою, є хороший шанс, що код генерації якось спрощується, дозволяючи йому вставляти деякі заяви, які не мають жодної функції в деяких випадках, а генерувати «чистий код» щоразу складніше. Або це, або код, який генерував вище, просто погано написаний :)

Ліберальне використання - {...}це ще один приклад цього, більшість із них є зайвими, але простіше написати код, який вставляє їх у кожному випадку (можливо, у деяких ви хочете перенаправити вихід / вхід блоку), а не розрізняти ті, де вони не потрібні, і опускають їх.


У нього є мета. Дивіться відповідь @ rici.
Старий Про

1

(exit 1)це простий, мабуть, найпростіший спосіб отримати певний код виходу (в спеціальному випадку 1, звичайно, є більш прості способи). Але це не є причиною в цьому випадку, оскільки код виходу не вивчається.

Метою введення exitв допоміжну оболонку може бути не вихід зі скрипту (хоча використання виходу для створення певного коду виходу).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.