Kiedy używać standardowego strumienia błędów w aplikacji wiersza poleceń?

9

Czy istnieją wytyczne, kiedy należy użyć błędu podczas pisania aplikacji wiersza polecenia? Ku mojemu zdziwieniu, nie znalazłem niczego, przeglądając go w Google.

W szczególności pytanie, które mnie teraz interesuje, brzmi: czy użyć stdoutlub stderrkiedy użytkownik wywołał program z nielegalnymi argumentami. Jednak bardziej doceniana jest bardziej kompleksowa odpowiedź, ponieważ z pewnością nie będzie to jedyny przypadek, w którym do napisania programu zachowującego się w sposób zgodny z oczekiwaniami użytkownika potrzebna jest jasna reguła.

UTF-8
źródło
Czy te komunikaty o błędach mogą być pomieszane ze zwykłymi danymi wyjściowymi? Np. Czy program jest filtrem danych?
thrig 12.01.17
To nie jest filtr danych. To również nie jest interaktywne. Użytkownik nazywa go argumentami (między innymi ścieżkami plików), programy działają, zmieniają te pliki, drukują kilka komunikatów, idealnie nie drukują żadnych komunikatów o błędach i kończą działanie.
UTF-8

Odpowiedzi:

15

Tak, wyświetlaj komunikat, stderrgdy używane są nieprawidłowe argumenty. A jeśli spowoduje to również zamknięcie aplikacji, wyjdź z niezerowym statusem wyjścia.

Powinieneś używać standardowego strumienia błędów do komunikatów diagnostycznych lub interakcji użytkownika. Komunikaty diagnostyczne obejmują komunikaty o błędach, ostrzeżenia i inne komunikaty, które nie są częścią danych wyjściowych narzędzia, gdy działa ono poprawnie („poprawnie” oznacza, że ​​nie dzieje się nic wyjątkowego, na przykład nie znaleziono plików lub cokolwiek to może być).

Wiele powłok (wszystkie?) Wyświetla monity, typy użytkowników, menu itp. stderr, Aby przekierowanie stdoutnie powstrzymało cię od interakcji z powłoką w znaczący sposób.

Poniżej znajduje się post z bloga na ten temat:

To cytat Douga McIllroya, wynalazcy rur uniksowych, wyjaśniający, jak to się stderrstało. „v6” odnosi się do wersji określonej wersji oryginalnego systemu operacyjnego Unix, która została wydana w 1975 r.

Wszystkie programy umieściły diagnostykę na standardowym wyjściu. Zawsze powodowało to problemy, gdy dane wyjściowe były przekierowywane do pliku, ale stawały się nie do zniesienia, gdy dane wyjściowe były wysyłane do niczego niepodejrzewającego procesu. Niemniej jednak, nie chcąc naruszać prostoty standardowego modelu wejścia-standardu-wyjścia, ludzie tolerowali ten stan rzeczy poprzez wersję 6. Niedługo potem Dennis Ritchie odciął węzeł gordyjski, wprowadzając standardowy plik błędu. To nie wystarczyło. W przypadku potoków diagnostyka może pochodzić z kilku programów działających jednocześnie. Diagnostyka potrzebna do identyfikacji.
- Doug McIllroy, „A Research UNIX Reader: Annotated Excerpts from the Programmer's Manual, 1971-1986”

„Identyfikacja siebie” oznacza po prostu powiedzenie „Hej! To ja mówię! To poszło nie tak: [...]”:

$ ls nothere
ls: nothere: No such file or directory

Robi to na stderrkorzystne, gdyż w przeciwnym razie może to być odczytane przez co czytałem na stdout(ale nie rób tego przy lskażdym razie , prawda?).

Kusalananda
źródło
Kiedy więc pytasz użytkownika, gdy aplikacja jest uruchomiona, powinieneś wydrukować pytanie na stderr? To nie brzmi dobrze. Czy masz na to źródło? Czy dotyczy to tylko aplikacji, które mają wyjście inne niż tylko pytania i odpowiedzi (wyjście, które użytkownik może chcieć gdzieś potokować)?
UTF-8
@ UTF-8 Czy tekst pytania powinien być uważany za część wyniku programu? Co z tym, co wpisuje użytkownik? Nie sądzę, że tak powinno być (podobnie jak muszle nie powinny tak być). Ale może zależy to od aplikacji?
Kusalananda
1
Dziękujemy za edycję. W międzyczasie sprawdziłem zachowanie standardowych aplikacji i zachowują się one tak, jak można by się spodziewać po przeczytaniu Twojej odpowiedzi.
UTF-8
@ UTF-8 możesz znaleźć to pytanie
terdon
6

Ze specyfikacji POSIX dla standardowych strumieni:

Podczas uruchamiania programu należy wstępnie zdefiniować trzy strumienie i nie trzeba ich jawnie otwierać: standardowe wejście (do odczytu konwencjonalnego wejścia), standardowe wyjście (do zapisu konwencjonalnego wyjścia) i standardowy błąd (do zapisu wyjścia diagnostycznego ).

Innymi słowy, błędy, informacje debugowania i wszystko, co należy do kategorii diagnostycznej, obejmuje stderr.

Zobacz podobne pytanie, aby uzyskać więcej informacji: czy raporty postępu / informacje o logowaniu należą do stderr czy stdout?

Sergiy Kolodyazhnyy
źródło