理解bash“;执行官1>&;2“;命令

理解bash“;执行官1>&;2“;命令,bash,exec,Bash,Exec,我看到一个bash脚本,它的函数中有exec1>&2命令。比如: function example() { exec 1>&2 cat <<EOT Script requires at least one parameter. EOT exit 1 } 函数示例() { 执行器1>&2 cat&2不是命令。有人能解释一下exec 1>&2命令背后的细节(尤其是为什么问题)吗?原始来源: exec filename命令将stdout重定向到指定

我看到一个bash脚本,它的函数中有
exec1>&2
命令。比如:

function example()
{
    exec 1>&2
    cat <<EOT
Script requires at least one parameter.
EOT
    exit 1
} 
函数示例()
{
执行器1>&2
cat&2不是命令。有人能解释一下
exec 1>&2
命令背后的细节(尤其是为什么问题)吗?

原始来源:

exec filename命令将stdout重定向到指定的文件。这会将所有通常会转到stdout的命令输出发送到该文件

请注意,exec N>filename会影响整个脚本或当前shell。从此点开始脚本或shell的PID中的重定向已更改。但是,N>filename只影响新分叉的进程,而不影响整个脚本或shell


进一步阅读你会感兴趣的内容,你可以找到@。你可以做很多简单的重定向技巧。

exec
是一个内置的Bash函数,因此它可以具有外部程序无法具备的特殊行为。特别是,它具有以下特殊行为:

如果未指定命令,则所有重定向将在当前shell中生效

(这是从
help exec
给出的消息中引用的)

这适用于任何类型的重定向;例如,您还可以编写以下任意内容:

exec >tmp.txt
exec >>stdout.log 2>>stderr.log
exec 2>&1

(然而,它不适用于管道。)

为什么这是一个历史性的事故,没有什么好的理由

重定向运算符应用于任何程序(例如,
cat
),并添加了
&
表单以表示“从2复制文件描述符1”因为它是有用的。
&
语法的使用可能是因为它们没有特殊字符,
&
是毫无意义的,因为
&
的基本含义(但不要引用我的话)。这些东西都可以追溯到1977年左右的伯恩·谢尔早期

为什么
exec
加上重定向来改变当前shell的输入和输出?可能是因为null命令
>path
已经有了意义,它与
cat/dev/null>path
具有相同的效果,但更容易键入,而且当电传打字机以每秒10个字符的速度运行时,这一点很重要o然后,内置的
exec
被重载:在没有参数的情况下,它将重定向操作应用于自身


因为bash尽可能地遵守Bourne shell惯例,所以您会得到这些古董,正如您所怀疑的,您只需记住,尤其是当您试图给其他适当性别的成员留下深刻印象时(即“小鸡们挖出一个知道其i/o重定向奥秘的家伙”).

在这种情况下,代码是一种冗长的编写方式:
echo”脚本至少需要一个参数“1>&2
。此外,错误消息没有帮助;您必须猜测该参数是什么。更好的消息是:
echo”用法:$(basename$0.sh)filename[…]”1>&2“
告诉您(提醒您)关于正确的用法和要提供的内容。使用4行来完成一行的工作有点OTT。如果“echo”有很多行,那么重定向就更有意义了,但是仍然可以使用
cat1>&2@JonathanLeffler:我同意。在括号包装函数的开头放
exec 1>&2
是一种邪恶的行为这样做还可以做其他事情,因为该副作用在函数返回后仍然存在。(无可否认,该函数调用
exit 1
,但这个习惯用法甚至不应该存在。)@ruakh:一般来说,在一个函数中使用它不是很好,但是如果这是函数的预期行为,它可能是正确的。这个成语本身是有用的,使用得当。这是一个非常边缘化的“正确使用”的例子(比如,我认为它在错误的边界的某个地方,进入了“不正确使用”的领域)@JonathanLeffler:是的,我想我们是同意的。如果函数的预期行为是重定向标准输出,那是一回事;但是如果它做了其他事情,那么它就不应该只是顺便重定向标准输出。“小鸡挖。。。“?耶,乐观主义者!+1,这是你的最后一句话。显然,没有什么比bash知识的深度更吸引人了。