Захоплення коду виходу команди виходу


10

Я маю це у сценарії bash:

exit 3;

exit_code="$?"

if [[ "$exit_code" != "0" ]]; then
    echo -e "${r2g_magenta}Your r2g process is exiting with code $exit_code.${r2g_no_color}";
    exit "$exit_code";
fi

Схоже, він вийде відразу після команди "exit", що має сенс. Мені було цікаво, чи існує якась проста команда, яка може надати вихідний код, не виходячи відразу?

Я збирався здогадатися:

exec exit 3

але він видає повідомлення про помилку: exec: exit: not found. Що я можу зробити? :)


1
Так, exec exit 3це не буено, я розумію"exec: exit: not found"

7
Я не розумію питання. Чому б не встановити exit_code=3та усунути exit 3лінію взагалі?
— wjandrea

@wjandrea - це скоріше концептуальне питання, ніж практичне

2
Для мене це все ще не має сенсу. Навіщо існувати код виходу, якщо ви насправді не виходите?
— Бармар

1
@Barmar у кожному процесі є вихідний код. Більшість людей, які намагаються відповісти на питання, інтерпретують це питання таким чином, "що я можу замінити" вихід 3 "у сценарії, щоб він встановив $?змінну, але не вийшов із цього сценарію"?
— ікар

Відповіді:


32

Якщо у вас є сценарій, який запускає якусь програму і дивиться на стан виходу програми (з  $?), і ви хочете перевірити цей сценарій, зробивши щось, що спричиняє $?встановлення якогось відомого значення (наприклад,  3), просто зробіть

(exit 3)

В дужках створюється підзагін. Потім exitкоманда призводить до того, що під-оболонка виходить із заданим статусом виходу.


Крім того, для налагодження було б так само просто встановити exit_code="3"тестування
— Centimane


12

exitце вбудований баш, тому ви не можете цього execзробити. За керівництво Баш по :

Статус виходу Баша - це статус виходу останньої команди, виконаної в сценарії. Якщо команди не виконуються, стан виходу 0.

Збираючи все це разом, я б сказав, що ваш єдиний варіант - зберегти бажаний статус виходу у змінну, а потім, exit $MY_EXIT_STATUSколи це доречно.


хммм, що ти думаєш про ідею @ G-man?

2
Можливо, я неправильно зрозумів те, що ви намагаєтеся досягти. Якщо ви просто намагаєтесь встановити $?(хоча я не дуже впевнений, чому ви це зробите), це здається твердою відповіддю. Якщо ви просто хочете встановити це якесь невдале значення, falseє інший варіант.
— соларшадо

10

Ви можете написати функцію, яка повертає статус, заданий як аргумент, або 255якщо такий не заданий. (Я називаю це так, retяк він "повертає" свою цінність.)

ret() { return "${1:-255}"; }

і використовувати retзамість вашого дзвінка до exit. Це дозволяє уникнути неефективності створення підрозділу в прийнятій відповіді.

Деякі вимірювання.

time bash -c 'for i in {1..10000} ; do (exit 3) ; done ; echo $?'

на моїй машині йде близько 3,5 секунд.

 time bash -c 'ret(){ return $1 ; } ; for i in {1..10000} ; do ret 3 ; done ; echo $?'

на моїй машині йде близько 0,051 секунди, в 70 разів швидше. Якщо введення в дію за замовчуванням все ще залишає це в 60 разів швидше. Очевидно, що петля має деяку накладну. Якщо я поміняю тіло циклу на просто так, :або trueчас зменшився вдвічі до 0,025, абсолютно порожній цикл є недійсним синтаксисом. Додавання ;:до циклу показує, що ця мінімальна команда займає 0,007 секунд, тому накладні витрати циклу становлять приблизно 0,018. Якщо відняти цей наклад з двох тестів, видно, що retрішення в 100 разів швидше.

Очевидно, це синтетичне вимірювання, але речі складаються. Якщо ви робите все в 100 разів повільніше, ніж потрібно, тоді ви закінчуєте повільні системи. 0,0


2
@iBug Додатковий простір не потрібен.
— ікар

Хороший момент щодо неефективності створення підкольовки. Я читав, що деякі снаряди можуть бути досить розумними, щоб оптимізувати вилку у таких випадках, але цей баш не один із них.
— G-Man каже: "Відновіть Моніку"

3

Про exec exit 3... він би спробував запустити зовнішню команду під назвою exit, але її немає, тому ви отримаєте помилку. Це має бути зовнішня команда, а не одна вбудована в оболонку, оскільки вона повністю exec замінює оболонку. Що також означає, що навіть якби у вас була викликана зовнішня команда exit, ви exec exit 3не повернетесь до продовження сценарію оболонки, оскільки оболонки вже не буде .


1
Я думаю, ти міг би зробити це exec bash -c "exit 3", але на даний момент я не можу придумати будь-якої причини зробити це, а не просто exit 3.
— David Z

1
@DavidZ, у будь-якому випадку, exec"ing або просто exit" ing зупинить сценарій, який не схожий на те, що запитання хотілося.
— ilkkachu

3

Ви можете зробити це за допомогою Awk:

awk 'BEGIN{exit 9}'

Або Sed:

sed Q9 /proc/stat

... або зі шкаралупою:sh -c 'exit 9'
— ilkkachu

1
@ilkkachu, якщо ти збираєшся це зробити, то можеш зробити так само (exit 9)у прийнятій відповіді
— Стівен Пенні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.