Прежде всего, вам нужно понять n> & m
синтаксис. это операция дублирования, то есть копирование m в n. ознакомьтесь с разделом «3.6.8 Дублирование файловых дескрипторов» .
У меня были те же сомнения, что и у вас, когда я изучал статью. Итак, я могу попытаться объяснить вам это:
ls > dirlist 2>&1
с помощью приведенной выше команды вы сначала перенаправляете вывод в dirlist с помощью > dirlist
. 2> & 1
означает копирование дескриптора файла с 1 на 2, другими словами, сделать fd2 копией fd1. Теперь fd1 уже указывает на dirlist, делая fd2 копией fd1, означает, что fd2 также указывает на dirlist. В итоге fd1-> dirlist, fd2-> dirlist.
ls 2>&1 > dirlist
с этим вы сначала делаете fd2 копией fd1, который все еще является терминалом, поэтому fd2-> terminal. затем вы перенаправляете fd1 на dirlist. в итоге fd2 -> terminal, fd1-> dirlist.
Направления обрабатываются слева направо.
ls > dirlist 2>&1
Заставьте оболочку, которая в конечном итоге превратится в ls, выполнить следующие системные вызовы (проверка ошибок опущена для краткости).
/* Handle > dirlist */
int temp_fd = open("dirlist",O_WR); /* Open dirlist for output */
dup2(temp_fd, 1); /* Make file descriptor 1 (stdout) point to dirlist */
close(temp_fd); /* Don't need this other file descriptor for dirlist */
/* Handle 2>&1 */
dup2(1,2); /* Make fd 2 be a copy of fd 1, which points to dirlist */
То есть сначала изменяется fd 1, а затем fd 2.
И наоборот, ls 2>&1 > dirlist делает
/* Handle 2>&1 */
dup2(1,2); /* Make fd 2 be a copy of fd 1, the original stdout */
/* Handle > dirlist */
int temp_fd = open("dirlist",O_WR); /* Open dirlist for output */
dup2(temp_fd, 1); /* Make file descriptor 1 (stdout) point to dirlist */
close(temp_fd); /* Don't need this other file descriptor for dirlist */
Другой способ посмотреть на это - это просто присваивания. Первоначально fd1=initial_stdout, затем
/* ls > dirlist 2>&1 */
fd1=to_dirlist
fd2=fd1 (i.e. to_dirlist)
/* ls 2>&1 > dirlist */
fd2=fd1 (i.e. initial_stdout)
fd1=to_dirlist.
Или вы можете сказать копирование по значению
, а не копирование по ссылке
.