重定向命令中的空格

重定向命令中的空格
program 2> error.log 
program &> filename 
program >> filename 2>&1
program 2>&1

我能够弄清楚这几行字的含义。

但是我不太明白应该把空格放在哪里。我还担心把空格放在哪里其实并不重要。谢谢阅读。

答案1

是的,单词和重定向之间的间距无关紧要。这是简短的回答。

细节在于,shell(为了简单起见,我们仅引用bash)将某些字符和字符组视为“单词”和“元字符”。摘自 bash 4.3 手册:

元字符

不加引号时用于分隔单词的字符。以下之一:

|  & ; ( ) < > space tab

单词 shell 认为是单个单位的字符序列。也称为标记。

因此,当我们这样做时:

$ echo "hello world">/dev/null

或者

$ echo "hello world" > /dev/null

这仍然是 3 个单词(“hello world” 可以被视为一个 shell 单词,因为它被引号括起来了),带有一个>元字符和几个空格。Shell 将看到它,并首先执行重定向(因此它首先查找元字符),然后根据其标准行为运行命令。

但是,重定向的顺序非常重要,尤其是当您使用类似 之类的东西复制文件描述符时2>&1。假设您想将 stderr 和 stdin 发送到同一位置。以下是错误的做法:

$ stat ./non-existent file 2>&1  > /dev/null
stat: cannot stat './non-existent': No such file or directory
stat: cannot stat 'file': No such file or directory

您正在将文件描述符2输出到与 相同的位置1,即您的终端,但它已经这样做了。这就是 stderr 出现的原因。

如果你stdout先重定向,然后再改变2指向的位置,那么它就会起作用:

$ stat ./non-existent file > /dev/null 2>&1 

答案2

除少数特殊情况外,间距并不重要。

  1. 标准输出重定向前有一个数字。
    根据Bash 手册

如果省略文件描述符编号,并且重定向运算符的第一个字符为 '<',则重定向指向标准输入(文件描述符 0)。如果重定向运算符的第一个字符为 '>',则重定向指向标准输出(文件描述符 1)。

因此,例如,echo test 2 > output.txt将被解释为echo test 2 1> output.txt,即将命令的标准输出重定向echo test 2到文件 output.txt,这将创建包含文本“test 2”的文件。
另一方面,echo test 2> output.txt将被解释为“将命令的标准输出(文件描述符 2)重定向echo test到文件 output.txt”,该文件将为空,因为命令的标准输出为空。
此行为不仅限于数字 1 和 2。因此echo test 5> output.txt还将创建一个空文件。

  1. <(...)当以或形式使用进程替换时>(...),左括号与 > 或 < 之间的空格不允许

请注意,< 或 > 和左括号之间不能有空格,否则该构造将被解释为重定向。

相关内容