Jak ukryć dane wyjściowe polecenia, ale pokazać, czy polecenie kończy kodowanie błędu?
Niestety założenie, że stderr
jest używany tylko do wyświetlania błędów, nie zawsze jest poprawny. Raczej, stderr
jest często używany dla wszystkich interaktywny wyjście i diagnostyka, tj. wyjście przeznaczone dla użytkownika do odczytania w interaktywnym pytaniu 1 . wget
i dd
są dobrze znane przykłady.
Niektóre polecenia dostarczą flagę (np. -quiet
lub -silent
) aby pominąć wyjście bez błędów - przeczytaj strony podręcznika, aby zobaczyć, czy istnieje.
Inną konwencją, która częściej się trzyma, jest konwencja kod wyjścia : program zwraca kod wyjścia, gdy wychodzi. Zazwyczaj 2 , kod wyjścia 0
wskazuje sukces, a każdy inny kod wyjścia wskazuje błąd.
Z bash
, możesz uzyskać kod wyjścia ostatniego polecenia z $?
zmienna. W fish
, Użyj $status
zmienna. Możesz fajkować stderr
do pliku tymczasowego i wydrukuj go tylko w przypadku wystąpienia błędu. Na przykład ( fish
):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Możesz także użyć niektórych skrótów, jeśli nie łączysz poleceń:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Lub:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
Możesz także fajkować stdout
do tego samego bufora za pomocą 2>&1 >/tmp/outputbuffer
.
(Uwaga: właściwie nie wiem fish
, więc dostosowuję koncepcję do tego, co mogę znaleźć w jej dokumentacji. Składnia może być nieco błędna. Możesz także użyć mktemp
aby wygenerować unikalny plik tymczasowy - uruchom go i zapisz nazwę pliku w zmiennej.)
Jeśli chcesz uruchomić całą rzecz w tle powłoki, której używasz także interaktywnie w tym samym czasie, lepiej napisać skrypt do obsługi ukrywania wyjścia i uruchamiania tego skryptu w tle za pomocą standardowe techniki ( fish
). Do cholery, możesz umieścić coś w rodzaju następującej funkcji ~/.config/fish/config.fish
:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
Zadzwoń z run-silent somecommand &
(gdzie trailing &
powoduje, że działa w tle)
Zauważ, że spowoduje to połknięcie oryginalnego kodu wyjścia i spowoduje zrzucenie obu stdout
i stderr
w przypadku awarii. Możesz dostosować go w razie potrzeby.
1 Nie ma nawet gwarancji, że wyjście błędu nie pojawi się stdout
- niektóre programy zrzucają tam wszystkie dane wyjściowe!
2 Niestety, nie zawsze tak jest - kod wyjścia jest całkowicie kontrolowany przez program, a niektóre wskazują na pewne warunki sukcesu przy niezerowych wyjściach. Ponownie sprawdź instrukcję.
Narzędzia uniksowe wysyłają ogólne wiadomości do
stdout
i komunikaty o błędach dostderr
, więc jeśli chcemy tylko wyświetlać komunikaty o błędach, wystarczy je wyłączyćstdout
tak tylkostderr
dostaje się do konsoli.Sposób, aby to zrobić (w obu
bash
ifish
) jest dołączać>/dev/null
do polecenia. Rury te przechodzą w nicość, ale stderr (z twoimi komunikatami o błędach) nadal trafia do konsoli.Na przykład:
Komenda
echo 1 >/dev/null
nic nie drukuje, ponieważ normalnestdout
wyjście jest wyłączone i nic nie zostało zapisane na stderr.Komenda
man doesnotexist >/dev/null
drukuje komunikat o błędzie, ponieważman
zapisuje swój komunikat o błędzie dostderr
.źródło
Spowoduje to uruchomienie polecenia w tle i zapisanie błędów w pliku dziennika, ignorując normalne wyjście
źródło