sh a.sh <&0 >&0
- 这是什么意思?特别是我不太清楚什么&0
意思。
答案1
n>&p
和n<&p
是相同的操作符,用于将文件描述符 (fd) 复制p
到文件描述符 上n
。换句话说,它们将文件描述符重定向n
到 fdp
重定向到的任何资源。
和<
不>
用于确定重定向文件描述符的使用方向(读或写)。n
将得到与 相同的方向p
。也就是说,如果p
是开放写入的,那么即使使用n
该运算符也是如此。n<&p
两个运算符之间的唯一区别是何时n
未指定。>&p
重定向 stdout(类似于1>&p
or 1<&p
)并<&p
重定向 stdin(类似于0<&p
or 0>&p
)。
所以<&0
就像0<&0
, so 将 stdin 重定向到 stdin 重定向到的任何资源,所以没有任何有用的东西,它通常是无操作并且没有多大意义。
但并不总是无操作,并非在每个 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
通常会以读+写模式打开终端设备,并将 fd 0、1 和 2 分配给它。
因此,也许编写此内容的人想要将 stdout 重定向到终端,假设 stdin 指向它。
一个有意义的地方n>&n
是 zsh 及其mult_IOs
功能。在zsh
:
some-cmd >&1 > some-file
# that is: some-cmd 1>&1 1> some-file
将 的标准输出重定向some-cmd
到 (&1) 和 之前的任何 stdout some-file
,就像您编写的那样:
some-cmd | tee some-file
尽管
some-cmd <&0 < some-file
# that is: some-cmd 0<&0 0< some-file
将首先提供原始的标准输入,然后some-file
作为输入,some-cmd
就像您编写的那样:
cat - some-file | some-cmd
但在 中cmd <&0 >&0
,fd 0 仅重定向一次,因此不适用。
n>&n
ksh
在某些 shell( 、zsh
、 not dash
、bash
nor )中还可能产生有趣的副作用,yash
因为如果文件描述符n
未打开,它会触发错误并放弃运行命令。所以,在那些贝壳里,
cmd 0<&0
将避免在关闭的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
答案2
在这种情况下,& 后跟一个数字表示文件编号。文件号 0 是标准输入 ( stdin
)。<
和字符>
分别表示进程的标准输入和标准输出的重定向。
因此,简而言之,此命令意味着运行a.sh
(sh
作为 shell 脚本),将脚本(实际上是子 shell)的标准输入和输出重定向到标准输入。
在这种情况下,<&0
是多余的(这是默认行为)。 >&0
意味着它将相对于父 shell 将原本在标准输出上打印的内容打印到标准输入上。大多数 tty 都会回显此类输出,因此重定向几乎没有效果,并且可能没有可见的效果。
一种合理的情况是父 shell 的标准输出文件被奇怪地关闭。这是一个奇怪的边缘情况。