Ненульовий стан виходу для чистого виходу


15

Чи прийнятно повернути ненульовий код виходу, якщо програма, про яку йде мова, працює належним чином? Наприклад, скажіть, що у мене проста програма, яка (лише) виконує такі дії:

Програма приймає N аргументів. Він повертає код виходу min (N, 255). Зверніть увагу, що будь-який N дійсний для програми.

Більш реалістична програма може повертати різні коди для успішно запущених програм, що означають різні речі. Чи повинні замість цього програми записувати цю інформацію в потік, наприклад, в stdout?

Відповіді:


24

Це залежить від оточення, але я б сказав, що це поганий стиль.

У Unix-подібних системах є чітка конвенція, що статус виходу 0 позначає успіх, а будь-який ненульовий статус виходу позначає збій. Деякі програми, але не всі програми, розрізняють різного роду збої з різними ненульовими кодами виходу; наприклад, grepзазвичай повертає 0, якщо шаблон знайдено, 1, якщо його не було, і 2 (або більше), якщо сталася помилка, наприклад, файл, що відсутній.

Ця конвенція досить сильно з'єднана з оболонками Unix. Наприклад, у sh, bashта інших оболонках, подібних до Борна, ifоператор вважає статус виходу 0 0 успішним / істинним, а ненульовий статус виходу як відмовою / помилкою:

if your-command
then
    echo ok
else
    echo FAILURE
fi

Я вважаю, що умови в MS Windows схожі.

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

Звичайний спосіб повернення програми такої інформації - це друк її на stdout:

status = $(your-command)
echo Result is $status

7
+1 для пояснення конвенції, цей підхід зламає більшість моїх сценаріїв оболонок, якби я set -eкудись поклав .
Бенджамін Баньє

Аналогічно до grep, diffповертає 1, коли виявляються відмінності; та> 1, якщо сталася помилка
7heo.tk

6

Залежить від того, що очікує ваше оточення.

Мій улюблений для wierdness, з Вікіпедії :

У OpenVMS успіх позначається непарними значеннями, а відмова - парними. Значення - це 32-бітове ціле число з підполями: контрольні біти, номер об'єкта, номер повідомлення та суворість. Значення тяжкості поділяються між успіхом (Успіх, Інформація) та невдачею (Попередження, Помилка, Фатальний).


4

Я думаю, що є прецедент, якщо код виходу повертає змістовну, відповідну інформацію абоненту, а визначення успіху насправді не є двійковим. Прецедент, про який я думаю, - це робокопія, яка повертає ряд різних речей залежно від того, що сталося .

Я додам, що у нас завжди виникає налагодження через це - більшість утилітів припускають вихідний код 0 == успіх, тому будьте злякані, коли роботопія повертається 1, оскільки вона копіювала матеріал не нульовий, тому що він не копіював матеріал, але не робив ' також не з’явиться помилка.


2

не повертати 0 за успішний запуск - це погана ідея, оскільки це може спричинити плутанину у тих, хто працює з вашою програмою. Що робити, якщо хтось запускав вашу програму 100+ разів з різним вкладом і хотів дізнатися, скільки не вдалося або успішно виконано, маючи єдине значення успіху, це набагато простіше помітити відмінності, ніж багато різних значень.

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


2

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

Він використовує коди виходу> 250 для позначення ненормальних виходів.

Хоча це і порушує конвенцію, на практиці це добре працює.


3
Я не думаю, що це не порушує умовності - тестування є успішним, якщо немає помилок; будь-який ненульовий код результату вказує на невдалі тести.
Беван

1
Це "вихід із статусом помилки, щоб вказати більше 0 помилок", і хоча це може порушити точну загальну семантику статусу виходу, воно, звичайно, не порушує більшого "0 добре, все, що більше 0, є помилка" .
Ватін

2

Це дійсно залежить від того, що ви намагаєтеся передати з кодом. Наприклад, DB2 повертає 100, якщо не знайдено даних, різних інших позитивних значень для попереджень та негативних значень для помилок. Oracle робить щось подібне.

Отже, якщо існують різні стани успіху, можливо, варто використовувати різні значення повернення.


2

Хороший приклад: людина-оновлення (spamassassin)

ВИХОДНІ КОДИ

  • Код виходу 0 означає, що оновлення було доступне, і воно було завантажено та встановлено успішно, якщо --checkonly не було вказано.
  • Вихідний код 1 означає, що оновлення не було доступно.
  • Код виходу з 2 означає ...

У цьому випадку вихід 1 - це просто інформаційний код. Однак, якби я написав код, я б не вибрав 1, оскільки зазвичай виходить з ладу.

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