当我运行这个命令时:
echo "1" > /dev/tty # runs successfully
但是当我运行这个时:
echo "1" | /dev/tty #permission denied
这两个运算符有什么区别>
,|
为什么管道会导致错误?
答案1
简短回答: >
后面必须跟一个文件名或&n
(n 是数字),并且|
后面必须跟另一个命令调用。
细节:在 shell 语法中,对某个命令的调用包含多个组件。例子:
A=foo 2>/dev/null B=bar cmd arg1 arg2 >file 3>&4 arg3
这里,parameters2>/dev/null
和>file
是3>&4
特殊参数(包含未转义的>
1),它们用于建立 io 重定向,并且可以出现在命令行中的任何位置。文件描述符 2 被重定向到/dev/null
,文件描述符1
(隐式)被重定向到file
,文件描述符3
被重定向到文件描述符 4 链接到的内容。
然后,在其余参数中,包含A=foo
和,因此它们不被视为命令名称:它们为要启动的进程的环境变量赋予特定值。B=bar
=
然后是命令cmd
和实际参数:arg1
, arg2
, arg3
。
管道|
不是命令调用的一部分,它将两个这样的调用链接在一起。例子:
CC=gcc make 2>&1 | LESS=--quit-at-eof less
第一个进程在文件描述符 1 上的输出将被第二个进程通过充当缓冲区的“管道”接收为文件描述符 0 上的输入。
—
1. 事实上,>
有时会看到像这样的特殊字符后面跟着一个空格。即使这是允许的,两个(空格分隔的)字符串也必须被理解为一个“实体”。
答案2
用于|
在进程之间传输数据,而>
用于将流重定向到文件。/dev/tty
是 root 拥有的“文件”/设备,其权限设置为 666,因此当您尝试通过管道传输到它时,您的 shell 会尝试执行 /dev/tty 以将数据传输到它,但它没有执行权限。