Istnieją dwie formy przekierowania standardowego wyjścia i standardowy błąd na standardowe wyjście . Ale który jest lepszy? i dlaczego &>
jest uważany za idealny?
Nie mogę znaleźć różnic, więc wiele samouczków, a nawet bash manualny stan &>
jest lepszy!
Dlaczego więc mam korzystać, &>
a nie korzystać?2>&1
Głównie za pomocą bash
powłoki
EDYCJA: Dzięki za komentatorów
Tylko> i działa w csh lub tcsh
W ksh działa tylko 2> i 1.
użyj myślnika> tylko plik 2> i 1 przekierowanie
Więc którego użyć, aby upewnić się, że mój skrypt jest kompatybilny z innymi systemami, niezależnie od używanych powłok!
command-line
bash
redirect
Maythux
źródło
źródło
&> somewhere
jest po prostu skrótem> somewhere 2>&1
: w słowach instrukcji bash są one „symantycznie równoważne”Odpowiedzi:
Strona podręcznika Bash wspomina, że istnieją dwa sposoby przekierowania stderr i stdout :
&> file
i>& file
. Teraz zauważ, że mówi zarówno stderr, jak i stdout.W takim przypadku
>file 2>&1
robimy przekierowanie stdout (1) do pliku, ale także informujemy stderr (2), aby został przekierowany w to samo miejsce co stdout! Cel może być taki sam, ale pomysł nieco inny. Innymi słowy „John, idź do szkoły; Suzzie idź tam, gdzie John”.Co z preferencjami?
&>
jestbash
rzeczą. Więc jeśli przenosisz skrypt, to tego nie zrobi. Ale jeśli masz 100% pewności, że twój skrypt będzie działał tylko na systemie z bash - nie ma preferencjiOto przykład z
dash
Debian Amquist Shell, która jest domyślną wersją Ubuntu.Jak widać, stderr nie jest przekierowywany
Aby uwzględnić zmiany wprowadzone w pytaniu, możesz użyć instrukcji if, aby sprawdzić zmienną $ SHELL i odpowiednio zmienić przekierowania
Ale w większości przypadków
> file 2>&1
powinno działaćMówiąc bardziej technicznie, formularz
[integer]>&word
nazywa się Duplikowaniem deskryptora pliku wyjściowego i jest funkcją określoną przez standard POSIX Shell Command Language, który jest obsługiwany przez większość powłok zgodnych z POSIX i podobnych do Brourne'a.Zobacz także Co dokładnie oznacza i oznacza przekierowanie danych wyjściowych?
źródło
&>
.... @Maythux W powłokach, które nie obsługują&>
np.dash
musisz użyć trywialnego>file 2>&1
przekierowania ..>file 2>&1
. Ta praca na wszystkich skorupach/etc/passwd
dla każdego użytkownika są powłokami interaktywnymi. Skrypty systemowe są zwykle używane,dash
chyba że określono inaczej. Jeśli chodzi o to, co jest domyślne, zależy to od tego, co jest dowiązane symbolicznie/bin/sh
w przypadku Ubuntudash
. W RHEL jestbash
, w FreeBSD jest totcsh
źródło i inne źródłoZasadniczo poleciłbym postępowanie Bourne'a ponownie , ponieważ bash jest prawdopodobnie najpopularniejszą powłoką uniksową. Bash zwykle używa albo
&>
albo2>&1
. IMHO, żadne nie jest „idealne”, więc polecam zapomnieć o tych bzdurach. Realistycznie, który powinieneś użyć, zależy od tego, co próbujesz zrobić.2>&1
łączy stderr z stdout, co może być przydatne, jeśli na przykład chcesz przesłać tekst stderr. Na przykład, jeśli chcesz zobaczyć, czy program drukuje określoną wiadomość stderr, ale nie chcesz, aby twój ekran był wypełniony (prawdopodobnie) nieistotnymi śmieciami, możesz zrobić coś takiegoprogram 2>&1 | grep crashed
, co przeszuka stdout i stderr z programu nazywany „programem” dla słowa „rozbił się”.Z drugiej strony, jeśli nie chcesz, aby jakiś program w ogóle coś drukował, możesz po prostu uruchomić
program &> /dev/null
, co przekieruje zarówno stderr, jak i stdout do / dev / null, specjalnego pliku, który magicznie znika. Lub, jeśli chcesz zapisać dane wyjściowe programu (być może w celu zgłoszenia błędu lub czegoś), możesz przekierować zarówno stderr, jak i stdout do pliku:program &> log.txt
przekieruje wszystkie dane do pliku o nazwie „log.txt”. Jeśli chcesz, możesz przekierować stdout i stderr przezprogram 2> log.txt > log.txt
lubprogram 2>&1 | cat > log.txt
, z których oba miałyby taki sam efekt jak użycie&>
. Jeśli zrobisz coś podobnegoprogram 2>&1 > file
, tylko stdout zostanie przekierowany, ale stderr może nadal zostać przekierowany do innego programu, takiego jak cat, który może zostać przekierowany, jak pokazano powyżej. Jednak pisanie&>
jest łatwiejszy niż jakikolwiek z powyższych przykładów, ponieważ polega na wpisywaniu mniejszej liczby znaków (i jest nieco łatwiejszy do odczytania przez ludzi). Pamiętaj,program 2> log.txt > log.txt
że bardziej prawdopodobne jest, że zadziała na powłokach innych niż bash.PS: jeśli martwisz się, że ludzie używają innych powłok, możesz dodać coś, co będzie pierwszą linią skryptu, zwaną „magiczną liczbą” lub „shebang”. Jest to zasadniczo sposób na upewnienie się, że inne komputery (szczególnie te z systemem operacyjnym Unix-podobnym) wiedzą, jakiego programu użyć do wykonania skryptu. Różne skrypty używają różnych shebangów. Shebang dla skryptu bash wygląda następująco:
Jeśli użyjesz powyższego jako pierwszego wiersza danego skryptu, bash będzie ogólnie używany do wykonania tego skryptu. To znacznie utrudni komuś przypadkowe wykonanie skryptu z niewłaściwą powłoką.
PS: Nie będę kłamał: do tej pory nie wiedziałem, że można go użyć
>&
, ale jeśli chodzi o bash, wydaje się, że działa tak samo jak&>
. Codziennie uczysz się czegoś nowego.źródło
#!
linii do jawnego żądaniabash
, nie zawsze jest ona dostępna w innych systemach. Bardzo często programiści / sysadmins muszą pisać przenośne skrypty dla systemów, w których instalacjabash
może być niedostępna i może nie być pod ich kontroląbash
.>file 2>&1
Jest po prostu znacznie przenośne.>file 2>&1
wiedzieć , że jest bardziej przenośny. Dokonam edycji, aby to odzwierciedlić.Z podręcznika użytkownika Bash -> 3.6.4 Przekierowanie standardowego wyjścia i standardowego błędu :
Również dobrze jest odnieść się do wiki Grega na temat danych wejściowych i wyjściowych -> 4.2. Manipulacja deskryptorem pliku :
źródło
2>&1
jest standardową powłoką Bourne / POSIX.&>
jest rozszerzeniem bash i nie jest standardem de jure .Jeśli piszesz skrypty przy użyciu rozszerzeń bash, prędzej czy później napotkasz zawroty głowy z komunikatami o błędach składni, ponieważ są one uruchamiane w standardowej powłoce.
źródło