Powiedzmy, że uruchamiam skrypt poleceń lub powłoki, co daje mi wynik. Nie znając wewnętrznych elementów tego polecenia lub skryptu powłoki, w jaki sposób można ustalić, czy dane wyjściowe pochodzą z stderr
lub stdout
?
Na przykład
$ ls -ld /
drwxrwxr-t 35 root admin 1258 Dec 11 19:16 /
vs
ls -ld /test
ls: /test: No such file or directory
Jak sprawdzić, czy pierwsze polecenie zostało wydrukowane, stdout
a drugie stderr
(czy to zrobiło?)?
io-redirection
KM.
źródło
źródło
stderred
w środowisku powłoki,LD_PRELOAD
aby uzyskaćstdout
istderr
w różnych kolorach. Oto powiązane pytanie w tym duchu.Odpowiedzi:
Nie ma sposobu, aby stwierdzić, kiedy wydruk został już wydrukowany. W tym przypadku oba
stdout
istderr
są podłączone do terminala, więc informacje, o których strumień został napisany został już utracone w momencie tekst pojawił się na terminalu; zostały połączone przez program, zanim dotarły do terminalu.Co można zrobić w takim przypadku jak wyżej, byłoby uruchomić komendę
stdout
istderr
przekierowany do różnych miejsc i zobaczyć, co się dzieje. Lub uruchom go dwukrotnie, raz zstdout
przekierowaniem do/dev/null
i raz zstderr
przekierowaniem do/dev/null
, i sprawdź, który z tych przypadków powoduje wyświetlenie tekstu.Można przekierować
stdout
do/dev/null
przez sklejaniu>/dev/null
się na końcu wiersza polecenia i można przekierowaćstderr
do/dev/null
dodając2>/dev/null
.źródło
Możesz przekierować stdout za pomocą
> file
i przekierować stderr za pomocą2> file
. Wiele nowoczesnych powłok obsługuje przekierowanie do poleceń, dzięki czemu można użyćsed
do podświetlenia, które dane wyjściowe pochodzą z którego strumienia:źródło
(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
annotate-output
Skrypt z Debianiedevscripts
pozwala to zrobić wybiórczo:Druga kolumna wskazuje stdout i stderr odpowiednio za pomocą
O
iE
.Jest kilka zastrzeżeń, z których głównym jest to, co zaznaczono w innych odpowiedziach: po fakcie nie można tego zrobić. Ani powłoka, ani terminal nie są świadomi tego, w jaki sposób dowolny program używa swoich deskryptorów plików, chociaż powłoka jest odpowiedzialna za ich początkowe ustawienie.
Ta metoda korzysta z fifos, pisanie do fifo może zachowywać się inaczej niż pisanie do tty, a pisanie do dwóch różnych fifo jest zdecydowanie inne (potencjalne problemy z synchronizacją / przeplotem). Ponadto nie nadaje się do użytku interaktywnego, np.
annotate-output bash
Nie jest świetnym planem, ale jest przydatny do wielu innych celów. Istnieje wiele przykładów skryptów i funkcji powłoki w odpowiedziach na pokrewne pytania dotyczące kolorowania stdin / stdout / stderr, najbardziej niezawodny jest stderrd, który wykorzystuje modyfikację (większość) programów uruchomieniowych do modyfikacji danych zapisanych do stderr.To pytanie, do którego prowadzi Anko, ma dobre odpowiedzi na ten powiązany temat: pokolorowanie wyjścia stdout / stderr: Czy mogę skonfigurować moją powłokę do drukowania STDERR i STDOUT w różnych kolorach?
źródło
bash
skrypt wykorzystującywhile read
pętle i uruchamiający jednodate
polecenie dla każdej linii stdout lub stderr, więc będzie o wiele mniej wydajny niż jegocmd > >(ts '%T O:') 2> >(ts '%T E:')
odpowiednik.Oprócz innych odpowiedzi wskazane jest
/proc/$PID/fd
(choć nie odpowiada na pytanie):Jak widać, tutaj można zobaczyć deskryptory plików otwarte dla procesu.
0
jestSTDIN
,1
jestSTDOUT
i2
jestSTDERR
. Jeśli nie przekierowano STDOUT lub STDERR, zobaczysz/dev/pts/33
(przynajmniej w tym przykładzie), ponieważ wskazywałyby na terminal.uwagi :
/proc/$PID
istnieje tylko dla uruchomionych procesów. W tym przypadku użyłemcat
bez argumentów, więc nie kończy się, dopóki nie zamknęSTDIN
. Wykonałem go również w tle, więc mam PID natychmiast ze względu na ten przykład.źródło
Nie jest do końca jasne, o co pytasz, ale to może pomóc
Źródło
Jeśli kod zakończenia wynosi 0, oznacza to po prostu, że polecenie zostało wykonane poprawnie (standardowe wyjście), tutaj możesz znaleźć znaczenie, jeśli kod wyjścia jest inny niż 0 (standardowe)
źródło
stdout
i niezerowystderr
?stderr
i zwracał dobry kod błędu lub pisałstdout
i zwracał zły kod błędu. W rzeczywistości spróbujfind /root
- zakładając, że nie działasz jako root, powinieneś wydrukować 2 linie - zostanie wydrukowane polecenie „/ root”stdout
, a polecenie „find: / root: odmowa uprawnień” zostanie wydrukowanestderr
. I find zwraca zły kod powrotu.Zwykle STDERR będzie miał nazwę programu dodaną do wiadomości dwukropkiem.
Przykład:
Vs
źródło
Aby przechwycić i przetestować dane wyjściowe błędu:
źródło