gfz*_*zhu 14 shell io-redirection
sh a.sh <&0 >&0
- 这是什么意思?特别是,我不是很清楚是什么&0
意思。
Sté*_*las 11
n>&p
和n<&p
是相同的运算符,用于将文件描述符 (fd)p
复制到文件描述符上n
。或者换句话说,他们将文件描述符重定向到n
fdp
重定向到的任何资源。
在<
和>
不使用,以确定哪些方向(读或写)重定向的文件描述符将被使用。n
将获得与 相同的方向p
。也就是说,如果p
是开放的,n
即使使用了n<&p
操作符也是如此。
两个运算符之间的唯一区别n
是没有指定when 。>&p
重定向标准输出(类似于1>&p
或1<&p
)并<&p
重定向标准输入(类似于0<&p
或0>&p
)。
所以<&0
就像0<&0
,所以将标准输入重定向到标准输入被重定向到的任何资源,所以没有任何用处,它通常是空操作并且没有多大意义。
但并非总是无操作,并非在每个 shell 中。禁用作业控制时,POSIX 要求将后台命令的 stdin 重定向到/dev/null
或等效文件。在 Bash 中(在 4.4.12 中测试)<&0
覆盖了这个。比较(ls -l /proc/self/fd/0 &)
和(<&0 ls -l /proc/self/fd/0 &)
。在某些情况下,这很有用。
>&0
将 fd 0 复制到 fd 1 上。因为 fd 1 (stdout) 按照惯例仅用于写入,>&0
只有在 fd 0 以读写模式打开时才有意义。
在 fd 0 指向终端设备的情况下就是这种情况,因为终端仿真器getty
通常会以读写模式打开终端设备并为其分配 fds 0、1 和 2。
因此,假设 stdin 指向它,那么写的人可能想将 stdout 重定向到终端。
一个n>&n
有意义的地方是 zsh 及其mult_IOs
功能。在zsh
:
some-cmd >&1 > some-file
# that is: some-cmd 1>&1 1> some-file
Run Code Online (Sandbox Code Playgroud)
将 的标准输出重定向some-cmd
到 (&1) 和 之前的任何标准输出some-file
,就像你写的一样:
some-cmd | tee some-file
Run Code Online (Sandbox Code Playgroud)
尽管
some-cmd <&0 < some-file
# that is: some-cmd 0<&0 0< some-file
Run Code Online (Sandbox Code Playgroud)
将首先提供原始标准输入,然后some-file
作为输入,some-cmd
就像你写的一样:
cat - some-file | some-cmd
Run Code Online (Sandbox Code Playgroud)
但是在 中cmd <&0 >&0
, fd 0 仅重定向一次,因此不适用。
n>&n
在某些 shell ( ksh
, zsh
, not dash
, bash
nor yash
) 中也可能有一个有趣的副作用,因为它会触发错误并在文件描述符n
未打开时放弃运行命令。所以,在那些贝壳里,
cmd 0<&0
Run Code Online (Sandbox Code Playgroud)
将避免cmd
在stdin
关闭的病理状态下运行:
$ ksh -c 'cat file - <&0' <&-
ksh: 0: cannot open [Bad file descriptor]
$ mksh -c 'cat file - <&0' <&-
mksh: <&0 : bad file descriptor
$ zsh -c 'cat file - <&0' <&-
zsh:1: 0: bad file descriptor
$ bash -c 'cat file - <&0' <&-
contents of file
cat: -: Bad file descriptor
cat: closing standard input: Bad file descriptor
Run Code Online (Sandbox Code Playgroud)
在这种情况下,& 后跟一个数字表示文件编号。文件号 0 是标准输入 ( stdin
)。和字符<
分别>
表示进程的标准输入和标准输出的重定向。
因此,简而言之,此命令意味着运行a.sh
(sh
作为 shell 脚本),将脚本(实际上是子 shell)的标准输入和输出重定向到标准输入。
在这种情况下,<&0
是多余的(这是默认行为)。 >&0
意味着它将相对于父 shell 将原本在标准输出上打印的内容打印到标准输入上。大多数 tty 都会回显此类输出,因此重定向几乎没有效果,并且可能没有可见的效果。
一种合理的情况是父 shell 的标准输出文件被奇怪地关闭。这是一个奇怪的边缘情况。