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


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.