W powłoce uniksowej, jeśli chcę połączyć stderr
i stdout
w strumień stdout
do dalszej manipulacji, mogę dodać poniższe na końcu mojej komendy:
2>&1
Tak więc, jeśli chcę użyć head
na wyjściu z g++
, mogę zrobić coś takiego:
g++ lots_of_errors 2>&1 | head
dzięki czemu zobaczę tylko kilka pierwszych błędów.
Zawsze mam problem z zapamiętaniem tego i ciągle muszę to sprawdzać, a to głównie dlatego, że nie do końca rozumiem składnię tej konkretnej sztuczki.
Czy ktoś może to rozbić i wyjaśnić znak po znaku co oznacza 2>&1
?
Deskryptor pliku 1 to standardowe wyjście (stdout
).
Deskryptor pliku 2 to standardowy błąd (stderr
).
Oto jeden ze sposobów zapamiętania tej konstrukcji (choć nie jest on całkowicie dokładny): na początku, 2>1
może wyglądać jak dobry sposób na przekierowanie stderr
do stdout
. Jednakże, w rzeczywistości będzie to interpretowane jako "przekieruj stderr
do pliku o nazwie 1
". &
wskazuje, że to co następuje jest deskryptorem pliku, a nie jego nazwą. Tak więc konstrukcja staje się: 2>&1
.
echo test > afile.txt
przekierowuje stdout do afile.txt
. To jest to samo, co zrobienie
echo test 1> afile.txt
Aby przekierować stderr, wykonujesz:
echo test 2> afile.txt
>&
jest składnią do przekierowania strumienia do innego deskryptora pliku - 0 to stdin, 1 to stdout, a 2 to stderr.
Możesz przekierować stdout na stderr robiąc:
echo test 1>&2 # or echo test >&2
Lub odwrotnie:
echo test 2>&1
Tak więc, w skrócie... 2>
przekierowuje stderr do (nieokreślonego) pliku, dołączenie &1
przekierowuje stderr na stdout.
Liczby te odnoszą się do deskryptorów plików (fd).
stdin
.stdout
.stderr
.2>&1
przekierowuje fd 2 na 1.
Działa to dla dowolnej liczby deskryptorów plików, jeśli program ich używa.
Możesz zajrzeć do /usr/include/unistd.h
jeśli je zapomniałeś:
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
To powiedziawszy, napisałem narzędzia C, które używają niestandardowych deskryptorów plików dla niestandardowego rejestrowania, więc nie'widzisz go, chyba że przekierujesz go do pliku lub czegoś.