Следует ли печатать использование командной строки на stdout или stderr?

При печати «использования» приложения это должно быть сделано на stdout или на stderr?

В зависимости от приложения я видел несколько случаев, но, похоже, нет единого правила. Может быть, я ошибаюсь, и есть одна хорошая практика. В таком случае, что это?


person Olivier Grégoire    schedule 04.02.2010    source источник


Ответы (8)


Никогда не думал об этом, но почему бы не записать инструкции по использованию в stderr, если программа была вызвана без аргументов или с неправильными аргументами, и записать их в stdout при вызове с аргументом --help (или подобным)? Таким образом, если использование показано из-за ошибки, оно переходит на стандартный вывод, а если это не ошибка, потому что пользователь запросил его, оно переходит на стандартный вывод. Логично как-то.

person OregonGhost    schedule 04.02.2010
comment
Я согласен. Вы также должны учитывать код выхода - если программа вызывается с неправильными аргументами, она должна возвращать 1, если она вызывается с --help или подобным, она должна возвращаться с 0. - person Alex Brown; 04.02.2010
comment
Спасибо за точность в отношении stdout при явном запросе (например, --help). Это сделало принятый ответ. - person Olivier Grégoire; 04.02.2010
comment
Спасибо, Алекс, за точность в отношении 0 и 1. Без вашего ответа здесь был бы другой вопрос ;) - person Olivier Grégoire; 04.02.2010
comment
@Alex: Полностью согласен, хотя, к сожалению, не существует общепринятого стандарта возвращаемых значений. Однако, на мой взгляд, ноль - это хорошее значение успеха. - person OregonGhost; 04.02.2010
comment
@OregonGhost: существует общепринятый стандарт. Программы всегда возвращают ноль в случае успеха и !0 в случае ошибки (хотя возвращаемые значения для ошибок не определены, они просто должны быть != 0). - person Morfildur; 04.02.2010
comment
@dbemerlin: Это теоретически. У меня есть много инструментов командной строки, которые возвращают какое-то значение, отличное от нуля, в случае успеха. Один из них возвращает 42, но есть и другие, которые возвращают множество вещей. Это означает, что вы просто не можете рассчитывать на то, что программа командной строки вернет ноль в случае успеха, что (на мой взгляд) означает отсутствие общепринятого стандарта. Было бы здорово, если бы это было так просто, но это не так. - person OregonGhost; 04.02.2010

Я согласен с тем, что явно запрошенное "использование" (с помощью опции -h, -? или --help) должно выводиться на стандартный вывод, а "использование", которое выводится в ответ на неправильный синтаксис или другие ошибки, должно отправляться к стдерр.

Однако обратите внимание, что все более популярная библиотека popt (которая обрабатывает синтаксический анализ командной строки; ее название означает «параметры синтаксического анализа») включает в себя средство для автоматического создания справки и что она всегда отправляет ее в stderr. Я цитирую справочную страницу popt:

Когда --usage или --help передаются программам, которые используют автоматическую справку popt, popt отображает соответствующее сообщение на stderr, как только находит параметр, и выходит из программы с кодом возврата 0.

Я считаю, что это всплывающая ошибка, но проблема в том, что POSIX (или ISO C, к которому он относится) никогда не определял, что имелось в виду под «диагностическим выводом». Просто прочитайте 'man stderr' или POSIX.1-2008.

person Urhixidur    schedule 10.01.2012
comment
Стандарты кодирования GNU говорят, что это идет к стандартному выводу. Интересно, есть ли у popt параметр конфигурации, чтобы сделать его совместимым. - person jww; 22.06.2017

Это может быть только мнение, но я думаю, что лучше всего написать в stderr. Таким образом, сообщение об использовании появляется, если пользователь совершает ошибку, даже если обычный вывод был перенаправлен.

person Community    schedule 04.02.2010

Я бы использовал STDERR, так как простое помещение его в STDOUT может вызвать проблемы с конвейерным выводом, и он появится в журналах для cronjobs, чтобы вам было легче заметить ошибку.

person Morfildur    schedule 04.02.2010
comment
Я думаю, что вы правы насчет ошибок параметров, но почему использование должно быть в журналах cron? - person naugler; 12.11.2013

Меня всегда беспокоили программы, у которых много опций, не помещающихся на экране, но при запуске от имени program --help | less я ничего не вижу, так как справка фактически отправлена ​​в stderr.

Мне нравится идея явно запрошенного использования (т. е. опция --help) для отправки вывода на stdout. В случае неверных параметров, я думаю, нет необходимости отображать подробную информацию об использовании. На stderr обязательно должно быть отправлено сообщение об ошибке, например Invalid option "--some-option". Run "program --help" for usage information.. Если программа решит вывести информацию об использовании по умолчанию при недопустимых параметрах или при вызове без параметров, я думаю, что должно быть короткое сообщение об ошибке с жалобой на неправильное использование, но сама помощь может перейти на stdout.

person Gene Pavlovsky    schedule 19.04.2016

если --help, то стандартный вывод, иначе стандартный вывод. Вот код JCommander для пользователей Java:

MyOptions myOptions = new MyOptions();
JCommander jCommander = new JCommander(myOptions);

try {
    jCommander.parse(args);
} catch (ParameterException exp) {
    /* print the exp here if you want */
    StringBuilder sb = new StringBuilder();
    jCommander.usage(sb);
    System.err.println(sb.toString());
    System.exit(1);
}

if(myOptions.isHelp()) {
    jCommander.usage();
    System.exit(0);
}
person Neil McGuigan    schedule 17.06.2016
comment
Спасибо, именно то, что я искал! - person Desik; 11.10.2016

По моему мнению, критерием является то, как появляется информация. Если требуется немедленная реакция или внимание, я помещаю его в stderr (потому что он не буферизован). Если это как-то информативно и не учитывает ошибок, то это для stdout.

person anthares    schedule 04.02.2010

Должна ли командная строка «использование» выводиться на стандартный вывод или на стандартный вывод?

Я думаю, это зависит от стандартов кодирования организации. За пределами организации это, вероятно, одна из тех тем, которые бесконечно обсуждаются, например, какая операционная система лучшая, какой редактор лучший, какая религия правильная...

При просмотре соглашений по коду Java (сентябрь 1997 г.) Java не указывает это . Ответа нет, и он будет бесконечно обсуждаться.

Согласно стандартам кодирования GNU, это должно быть напечатано на стандартном выходе:

4.7.2 --help

Стандартная опция --help должна выводить краткую документацию о том, как вызвать программу на стандартный вывод, а затем успешно завершить работу. Другие опции и аргументы должны быть проигнорированы, как только это будет видно, и программа не должна выполнять свою обычную функцию.

В конце вывода опции '--help' поместите строки, содержащие адрес электронной почты для отчетов об ошибках, домашнюю страницу пакета (обычно 'http://www.gnu.org/software/pkg' и общую страницу справки по использованию программ GNU. Формат должен быть таким:

Report bugs to: mailing-address
pkg home page: <http://www.gnu.org/software/pkg/>
General help using GNU software: <http://www.gnu.org/gethelp/>

Можно упомянуть другие соответствующие списки рассылки и веб-страницы.


Вот тема, связанная с "версией". Это также из руководства по кодированию GNU, и оно также записывает в стандартный вывод:

4.7.1 --версия

Стандартная опция --version должна указать программе вывести информацию о своем имени, версии, происхождении и юридическом статусе, все на стандартный вывод, а затем успешно завершить работу. Другие опции и аргументы должны быть проигнорированы, как только это будет видно, и программа не должна выполнять свою обычную функцию.

Первая строка предназначена для того, чтобы программу было легко анализировать; собственно номер версии начинается после последнего пробела. Кроме того, оно содержит каноническое название этой программы в таком формате:

GNU Emacs 19.30

Имя программы должно быть постоянной строкой; не вычисляйте его из argv[0]. Идея состоит в том, чтобы указать стандартное или каноническое имя программы, а не имя ее файла. Есть и другие способы узнать точное имя файла, в котором команда находится в PATH.

Если программа является дочерней частью более крупного пакета, укажите имя пакета в скобках, например:

emacsserver (GNU Emacs) 19.30

Если номер версии пакета отличается от номера версии этой программы, вы можете указать номер версии пакета непосредственно перед закрывающей скобкой.

Если вам нужно указать номера версий библиотек, которые распространяются отдельно от пакета, содержащего эту программу, вы можете сделать это, напечатав дополнительную строку информации о версии для каждой библиотеки, которую вы хотите упомянуть. Используйте тот же формат для этих строк, что и для первой строки.

Пожалуйста, не упоминайте все библиотеки, которые программа использует «просто для полноты картины» — это создаст бесполезный беспорядок. Пожалуйста, указывайте номера версий библиотек только в том случае, если на практике вы обнаружите, что они очень важны для вас при отладке.

Следующая строка после строки или строк с номером версии должна содержать уведомление об авторских правах. Если требуется более одного уведомления об авторских правах, поместите каждое на отдельной строке.

Далее должна следовать строка с указанием лицензии, желательно с использованием одной из приведенных ниже аббревиатур, и краткое заявление о том, что программа является свободным программным обеспечением и что пользователи могут свободно копировать и изменять ее. Также упомяните, что нет никаких гарантий, насколько это разрешено законом. См. рекомендуемую формулировку ниже.

Можно закончить вывод списком основных авторов программы, чтобы отдать должное.

Вот пример вывода, который следует этим правилам:

GNU hello 2.3
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

...

person jww    schedule 21.06.2017