Czytam przykładowy skrypt powłoki bash:
#!/bin/bash
# This script makes a backup of my home directory.
cd /home
# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1
# First remove the old bzip2 file. Redirect errors because this generates some if the archive
# does not exist. Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar
# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1
# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log
Próbuję zrozumieć użycie „/ dev / null 2> & 1” tutaj. Na początku myślałem, że ten skrypt używa / dev / null, aby z wdziękiem ignorować błędy bez powodowania awarii skryptu (coś w rodzaju próby obsługi wyjątków w językach programowania). Ponieważ nie widzę, jak użycie tar do skompresowania katalogu do pliku tar może spowodować jakiekolwiek błędy.
bash-script
null
JohnMerlino
źródło
źródło
/dev/null
nie zapobiegnie awariom, ale wyczyści strumienie wyjściowe stdout i stderr.tar
może powodować błędy na różne sposoby. Być może nie masz dostępu do zapisu, plik może już istnieć itp.tar
nie ma go w $ PATH, ponieważtar
zawiesił się (nigdy nie wiadomo), ponieważ na urządzeniu nie ma już miejsca, ponieważtar
wersja uległa zmianie i teraz wymaga innej składni, ponieważ dysk spowodował błąd we / wy. Jestem pewien, że możesz znaleźć więcej.Odpowiedzi:
Nie, nie zapobiegnie to awarii skryptu. Jeśli wystąpią jakiekolwiek błędy w
tar
procesie (np .: odmowa uprawnień, brak pliku lub katalogu, ...) skrypt nadal się zawiesi.Ponieważ użycie
> /dev/null 2>&1
przekieruje wszystkie dane wyjściowe polecenia (zarównostdout
istderr
)/dev/null
, co oznacza, że żadne dane wyjściowe nie są drukowane na terminalu.Domyślnie:
W skrypcie używasz
> /dev/null
powodując:A następnie
2>&1
powodując:źródło
> /dev/null 2>&1
, to polecenie powodujestderr ==> stdout
, więc stderr nadal jest drukowany na standardowe wyjście?fd
?CMD > /dev/null 2>&1
działa, aleCMD 2>&1 > /dev/null
wciąż daje mi STDERR?2>& 1
w przykładach kodu, aby podkreślić, że liczba i znak & są uważane za część operatora przekierowania. Przekierowanie do pliku często ma miejsce pomiędzy,>
a/path/to/file
przekierowanie do deskryptora pliku jest zasadniczo takie samo.(zwróć uwagę, że
/dev/null
w pytaniu dodałem przekierowanie ).Powyższe przekieruje
STDOUT
iSTDERR
do/dev/null
. Działa poprzez połączenieSTDERR
zSTDOUT
. (Zasadniczo wszystkie dane wyjściowe polecenia zostaną przekierowane do urządzenia zerowego .)To nie do końca tak
try/catch
. To po prostu wycisza każdy wynik (w tym błąd) z polecenia.Może to powodować błędy z wielu powodów, w tym:
źródło
Po uruchomieniu CMD> / dev / null 2> i 1
STDOUT przekierowuje na / dev / null, a następnie STDERR przekierowuje na ADRES STDOUT, który został ustawiony na / dev / null, w związku z czym zarówno STDOUT, jak i STDERR wskazują na / dev / null
Przeciwnie, po uruchomieniu CMD 2> i 1> / dev / null
STDERR przekierowuje na ADRES STDOUT (deskryptor pliku 1 w tym momencie lub / proc / self / fd / 1), a następnie STDOUT przekierowuje do / dev / null, ale STDERR ciągle przekierowuje do fd1 !! W rezultacie normalne wyjście z STDOUT jest odrzucane, ale błędy pochodzące z STDERR są nadal zapisywane na konsoli.
źródło
Przekierowanie We / Wy Bash
Główną ideą wyjaśnienia tego jest:
Więc ten kod:
przekierowuje
stderr
dostdout
najpierw (2>&1
), a następnie wysyłastdout
(łącznie z przekierowanymstderr
) dofilename
(> filename
). Oto wyjaśnienie ABSG (rozdz. 20) .Ten kod:
przekierowuje
stderr
istdout
do/dev/null
... co oznacza donikąd . Przesyłane rzeczy/dev/null
nie są w żaden sposób zapisywane, buforowane ani zapamiętywane.Są po prostu wysyłani do „ nigdzie ” i zapominani. Jest to sposób uruchamiania programów i upewnienia się, że nie generują one żadnych danych wyjściowych i nigdy nie będą widoczne w wierszu poleceń ani w pliku dziennika.
Widzę tego typu pytania dość często ... głównie dlatego, że musiałem to sprawdzić sam, ponieważ nie kodowałem od lat. Oto kilka przydatnych informacji z ABSG:
„Przekierowanie oznacza po prostu przechwytywanie danych wyjściowych z pliku, polecenia, programu lub skryptu i wysyłanie go jako danych wejściowych do innego pliku, polecenia, programu lub skryptu”.
ABSG: Advanced Bash Scripting Guide: Rozdział 20 Powyższy link jest link do przekierowania strony I / O z open source tldp.org dokumentu o nazwie Zaawansowane Bash Scripting Guide przez Mendla Coopera. Jest wymieniony jako „Dogłębna eksploracja sztuki skryptowania powłoki” i całkowicie się zgadzam. Jest to wspaniały zasób i ma mnóstwo odpowiedzi na wszelkiego rodzaju szalone sytuacje.
Inne cenne zasoby: W bieżącej / utrzymywanej sekcji znajduje się wiele cennych zasobów (w kilku przydatnych formatach, takich jak HTML, PDF, tekst itp.) Na stronie Przewodniki po dokumentacji dokumentacji systemu Linux . Oto kilka, które uważam za przydatne:
źródło
filename
, a następnie standardowy błąd jest przekierowywany do każdego miejsca, w którym obecnie standardowe wyjście jest (dofilename
). Gdyby było odwrotnie, błąd standardowy kończyłby się na terminalu, podczas gdy przekierowywano tylko standardowe wyjściefilename
. Ponadto, wcommand >file1 2>file2
,file2
nie zostałby utworzony, gdybyfile1
nie można go było utworzyć (bez względu na to, czyfile1
ifile2
faktycznie były to zupełnie inne ścieżki).