Co robi „2> i 1” w wierszu poleceń?

Odpowiedzi:

78

1Standardowe wyjście oznacza (wyjścia). 2Oznacza błąd standardowy (stderr).

2>&1Mówi więc o wysyłaniu standardowego błędu tam, gdzie przekierowuje się standardowe wyjście. Co, ponieważ jest wysyłane, /dev/nullprzypomina ignorowanie jakichkolwiek danych wyjściowych.

Chealion
źródło
2
Czy istnieje powód, dla którego znak 1 pojawia się przed 1, ale nie przed 2? Myślałem, że & jest zarezerwowaną postacią do uruchamiania zadania w tle, ale myślę, że to tylko wtedy, gdy znak ampersand pojawia się jako długi znak na końcu polecenia ...?
Matt Huggins
8
Ponieważ 0(stdin), 1(stdout) i 2(stderr) są w rzeczywistości deskryptorami plików, powłoka wymaga znaku ampersand umieszczonego przed nimi w celu przekierowania. W tym przypadku powiela deskryptor pliku, skutecznie łącząc ze sobą dwa strumienie informacji.
Chealion
12
Pomyśl o tym w ten sposób: gdybyś miał tylko „1” bez znaku handlowego, powłoka utworzyłaby plik o nazwie „1” i przekierowałaby do niego wyjście stderr.
CarlF,
1
Okej, czy to samo byłoby wtedy ważne? curl http://www.google.com 2>/dev/nullSkąd wiersz poleceń wie, że „2” ma oznaczać stderr i nie jest tak naprawdę drugim parametrem, który przekazuję do polecenia curl?
Matt Huggins
1
@Matt Huggins: Tak. To wysłałoby wszystkie dane wyjściowe od stderrprostej do /dev/nullzamiast. Widać to w praktyce poprzez próbę curl, curl 1>/dev/nulli curl 2>/dev/nullpo prostu zobaczyć zmianę sygnału wyjściowego. Znów ampersand jest potrzebny tylko do przekierowania deskryptora pliku.
Chealion
23

tl; dr

Pobierz http://www.google.comw tle i odrzuć zarówno stdouti stderr.

curl http://www.google.com > /dev/null 2>&1 &

jest taki sam jak

curl http://www.google.com > /dev/null 2>/dev/null &

Podstawy

0, 1I 2stanowią standardowe plików deskryptorów w POSIX systemów operacyjnych. Deskryptor pliku to systemowe odwołanie do (w zasadzie) pliku lub gniazda .

Utworzenie nowego deskryptora pliku w C może wyglądać mniej więcej tak:

fd = open("data.dat", O_RDONLY)

Większość poleceń systemu Unix pobiera dane wejściowe i wyprowadza wynik do terminala. curlpobierze wszystko, co jest pod określonym adresem URL ( google dot com ) i wyświetli wynik do stdout.

wynik zwijania

Przekierowanie

Tak jak powiedziałeś <i >służą do przekierowania wyjścia z polecenia do innego miejsca, na przykład pliku.

Na przykład, w ls > myfiles.txt, lspobiera zawartość bieżącego katalogu i >przekierowuje jego wyjście myfiles.txt(jeśli plik nie istnieje, to zostanie utworzony, w przeciwnym razie nadpisane, ale można użyć >>zamiast >dołączyć do pliku zamiast). Jeśli uruchomisz powyższe polecenie, zauważysz, że terminal nie wyświetla niczego. Zazwyczaj oznacza to sukces w systemach uniksowych. Aby to sprawdzić, cat myfiles.txtwyświetl zawartość pliku na ekranie.

> / dev / null 2> i 1

Pierwsza część > /dev/nullprzekierowuje stdout, to jest curlwyjście do /dev/null(więcej o tym naprzód) i 2>&1przekierowuje stderrdo stdout(który właśnie został przekierowany, /dev/nullwięc wszystko zostanie wysłane /dev/null).

Lewa strona 2>&1informuje o tym , co zostanie przekierowane, a prawa strona informuje, dokąd . &Stosowany jest po prawej stronie, aby odróżnić stdout (1)albo stderr (2)z plików nazwanych 1lub 2. Tak, 2>1by skończyć tworzenia nowego pliku (jeśli nie istnieje już) o nazwie 1i zrzucić stderrwynik tam.

/ dev / null

/dev/nulljest pustym plikiem, mechanizmem używanym do odrzucania wszystkiego, co do niego zapisano. Tak więc curl http://www.google.com > /dev/nullskutecznie tłumi curlwydajność.

> / dev / null

Ale dlaczego na terminalu są jeszcze jakieś rzeczy ?. To nie curl jest zwykłe wyjście, ale dane wysyłane do stderr, używane tutaj do wyświetlania postępu i informacji diagnostycznych, a nie tylko błędów .

curl http://www.google.com > /dev/null 2>&1ignoruje zarówno curldane wyjściowe, jak i curlinformacje o postępie. W rezultacie nic nie jest wyświetlane na terminalu.

Wreszcie

Na &końcu jest jak powiedzieć powłoce, aby uruchomiła polecenie jako zadanie w tle . Powoduje to natychmiastowe zwrócenie monitu, gdy polecenie jest uruchamiane asynchronicznie za sceną. Aby zobaczyć aktualne zadania, wpisz jobsw swoim terminalu. Uwaga: różni się to od procesów uruchomionych w systemie. Aby zobaczyć te, wpisz topw terminalu.

Bibliografia

Jorge Bucaran
źródło
1
To jedna z najlepszych odpowiedzi na całej stronie z punktu widzenia układu, dobra robota!
OmarOthman,
Nie rozumiem tylko, dlaczego chcesz wysłać wszystko /dev/null? Nie chcesz, żeby wyniki curlprzynajmniej gdzieś były przydatne?
skube
@skube Right. W tym przypadku nie jest dla mnie jasne, dlaczego użytkownik chce odrzucić zarówno stdout, jak i stderr. OP prawdopodobnie chciał po prostu zrozumieć, co oznacza składnia.
Jorge Bucaran
5

2odnosi się do STDERR. 2>&1wyśle ​​STDERR do tej samej lokalizacji co 1(STDOUT).

John T.
źródło
0

Rozumiem, co następuje:

Jeśli chcesz tylko odczytać informacje o wyjściu i błędzie polecenia na ekranie, po prostu napisz: curl http://www.google.com

Czasami chcesz zapisać informacje wyjściowe do pliku zamiast ekranu terminala do późniejszego przejrzenia, a następnie możesz napisać: curl http://www.google.com > logfile

Ale w ten sposób informacje StdErr zostaną pominięte, ponieważ >przekierowują tylko StdOut do logfile.

Jeśli więc zależy Ci na informacjach o błędzie polecenia, które nie wykonało się, musisz połączyć StdOut ze StdErr za pomocą 2>&1(co oznacza złóż StdErr na StdOut), aby można było napisać następującą linię poleceń: curl http://www.google.com > logfile2> i 1

YaOzI
źródło