如果 stdin 重定向到 fd4,为什么 read 可以工作?

如果 stdin 重定向到 fd4,为什么 read 可以工作?

下面的脚本是什么意思?

exec 4<&0 0</etc/XX/cfg
read line1
exec 0<&4

它将 fd0 重定向到 fd4,并将“/etc/XX/cfg”重定向到 fd0。

那么为什么read仍然有效,它不应该是空的吗?

答案1

它将 stdin (FD0) 重定向到 FD4,从 FD0 重定向/etc/XX/cfg到 FD0,从 FD0 读取一行,然后将 FD4 移回 FD0。简而言之,它保存、替换和恢复标准输入,同时从中间的文件中读取一行。

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

我阅读此内容的方式 - 基于 bash 手册页中有关重定向的部分 - 是将 (fd0) 重定向到 fd4,然后从intostdin获取输入- 最终将到达 fd4。/etc/XX/cfgstdin

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

您可以通过 test.sh 进行管道或重定向stdin,但也可以通过重定向读取配置,因此在上面的代码中,我从“config”中提取了值(我根据文件名进行假设 - 不好:)),但我也可以通过 stdin 进行处理。

例如:

$ ./test.sh < somefile
$ cat somefile | ./test.sh

希望这能解释它。

相关内容