Σε ένα κέλυφος Unix, αν θέλω να συνδυάσω τα stderr
και stdout
στη ροή stdout
για περαιτέρω επεξεργασία, μπορώ να προσθέσω τα ακόλουθα στο τέλος της εντολής μου:
2>&1
Έτσι, αν θέλω να χρησιμοποιήσω το head
στην έξοδο από το g++
, μπορώ να κάνω κάτι τέτοιο:
g++ lots_of_errors 2>&1 | head
έτσι ώστε να μπορώ να δω μόνο τα πρώτα λάθη.
Πάντα δυσκολεύομαι να το θυμάμαι αυτό, και πρέπει συνεχώς να πηγαίνω να το ψάχνω, και αυτό συμβαίνει κυρίως επειδή δεν κατανοώ πλήρως τη σύνταξη αυτού του συγκεκριμένου κόλπου.
Μπορεί κάποιος να το σπάσει και να εξηγήσει χαρακτήρα προς χαρακτήρα τι σημαίνει "2>&1";
Ο περιγραφέας αρχείου 1 είναι η τυπική έξοδος (stdout
).<br>,
Ο περιγραφέας αρχείου 2 είναι το τυπικό σφάλμα (stderr
).
Εδώ είναι ένας τρόπος για να θυμάστε αυτή την κατασκευή (αν και δεν είναι απόλυτα ακριβής): στην αρχή, το 2>1
μπορεί να φαίνεται σαν ένας καλός τρόπος για να ανακατευθύνετε το stderr
στο stdout
. Ωστόσο, στην πραγματικότητα θα ερμηνευτεί ως "ανακατεύθυνση του stderr
σε ένα αρχείο με όνομα 1
". Το &
υποδηλώνει ότι αυτό που ακολουθεί είναι ένας περιγραφέας αρχείου και όχι ένα όνομα αρχείου. Έτσι η κατασκευή γίνεται: 2>&1
.
echo test > afile.txt
ανακατευθύνει το stdout στο αρχείο afile.txt
. Αυτό είναι το ίδιο με το να κάνετε
echo test 1> afile.txt
Για να ανακατευθύνετε το stderr, κάνετε:
echo test 2> afile.txt
>&
είναι η σύνταξη για να ανακατευθύνετε μια ροή σε έναν άλλο περιγραφέα αρχείου - το 0 είναι το stdin, το 1 είναι το stdout και το 2 είναι το stderr.
Μπορείτε να ανακατευθύνετε το stdout στο stderr κάνοντας:
echo test 1>&2 # or echo test >&2
Ή το αντίστροφο:
echo test 2>&1
Οπότε, εν συντομία... Το 2>
ανακατευθύνει το stderr σε ένα (απροσδιόριστο) αρχείο, ενώ η προσθήκη του &1
ανακατευθύνει το stderr στο stdout.
Οι αριθμοί αναφέρονται στους περιγραφείς αρχείων (fd).
stdin
stdout
.stderr
2>&1
ανακατευθύνει το fd 2 στο 1.
Αυτό λειτουργεί για οποιονδήποτε αριθμό περιγραφέων αρχείων, αν το πρόγραμμα τους χρησιμοποιεί.
Μπορείτε να κοιτάξετε στο /usr/include/unistd.h
αν τους ξεχάσετε:
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
Τούτου λεχθέντος, έχω γράψει εργαλεία C που χρησιμοποιούν μη τυποποιημένους περιγραφείς αρχείων για προσαρμοσμένη καταγραφή, ώστε να μην το βλέπετε, εκτός αν το ανακατευθύνετε σε ένα αρχείο ή κάτι τέτοιο.