Что означает следующий сценарий?
exec 4<&0 0</etc/XX/cfg
read line1
exec 0<&4
Он перенаправляет fd0 на fd4, а «/etc/XX/cfg» на fd0.
Так почему же он read
все еще работает, разве он не должен быть пустым?
решение1
Он перенаправляет stdin (FD0) на FD4, перенаправляет с /etc/XX/cfg
на FD0, считывает строку из FD0, а затем перемещает FD4 обратно на FD0. Короче говоря, он сохраняет, заменяет и восстанавливает stdin, считывая строку из файла между этим.
read line1 < /etc/XX/cfg
было бы намного проще, но невозможно определить, является ли это допустимой заменой, основываясь только на показанном коде.
решение2
Чтобы перевести это в системные вызовы (используя C):
exec 4<&0 0</etc/XX/cfg
/* Duplicate fd0 as fd4. */
dup2 (0, 4);
/* Open file on fd0.
"open" always uses lowest available descriptor, so we don't need to check it. */
close (0);
open ("/etc/XX/cfg", O_RDONLY);
exec 0<&4
/* Close fd0 and duplicate fd4 as fd0. */
dup2 (4, 0);
решение3
Насколько я понимаю это (основываясь на разделе man-страницы bash о ПЕРЕНАПРАВЛЕНИИ), stdin
(fd0) перенаправляется в fd4, затем из него берется ввод /etc/XX/cfg
, stdin
который в конечном итоге попадает на fd4.
read line1
затем следует взять из fd4, который затем поместить обратно в fd0.
Демонстрация могла бы показать мой смысл немного лучше и ответить на вопрос «почему» вы могли бы это сделать. Добавив еще одну строку и поместив ее в обертку:
$ vim ./test.sh
#!/bin/bash
exec 4<&0 0</etc/XX/cfg
read line1 # reads from fd4
exec 0<&4
read line2 # reads from fd0
echo $line1
echo $line2
Вы можете передавать данные по конвейеру или перенаправлять их stdin
через test.sh, но также можете читать конфигурацию с помощью перенаправления, поэтому в коде выше я извлек значения из «config» (предположение с моей стороны, основанное на имени файла — плохое :) ), но я также могу обрабатывать данные через stdin.
например:
$ ./test.sh < somefile
$ cat somefile | ./test.sh
Надеюсь, это все объясняет.