
Я пришел к пониманию, что у нас есть два метода перенаправления stdout и stderr в один и тот же файл. Первый метод:
ls -l /bin > ls-output.txt 2>&1
Как авторэта книгаутверждает: Используя этот метод, мы выполняем 2 перенаправления: сначала мы перенаправляем stdout в ls-output.txt, а затем мы перенаправляем stderr (файловый дескриптор 2) в stdout (используя файловый дескриптор 1).
Порядок перенаправлений важен.
ls -l /bin 2>&1 >ls-output.txt
перенаправит stderr на экран.
Мой вопрос: как и во многих языках программирования, была ли команда разработана с учетом некоторых правил ассоциативности и приоритета?икак прочитать команду, пока она написана на экране?иКакова последовательность выполнения команды на внутреннем уровне?
Вот что я думаю о последовательности выполнения: Сначала команда ls -l /bin
отправляет свой вывод на stdout, а ошибку на stderr (любой из них). Затем stderr перенаправляется на stdout. (если есть какая-либо ошибка, например: if ls -l /binn
используется). Теперь поток stdout содержит один из двух (вывод или ошибку), который затем перенаправляется в файл.ls-вывод.txt
решение1
Перенаправления обрабатываются слева направо. Когда вы выполняете:
ls -l /bin >ls-output.txt 2>&1
оболочка выполняет внутри себя примерно следующие операции:
fork(); // Then in the child process:
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
// 2>&1
dup2(1, 2);
Затем он выполняет ls -l /bin
команду с этими прикрепленными дескрипторами. Поскольку вы stdout
сначала перенаправляете на файл, перенаправление stderr
наследует это перенаправление.
Если бы вы написали
ls -l /bin 2>&1 >ls-output.txt
Порядок операций будет обратным:
// 2>&1
dup2(1, 2);
// >ls-output.txt
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
Это подключается stderr
к оригинальному stdout
, который, скорее всего, является терминалом. Затем он перенаправляется stdout
в файл; это не оказывает никакого влияния на stderr
.