我如何从eval期间调用的陷阱中打印到stdout

时间:2019-02-04 12:29:46

标签: bash eval stdout trap

当我按下 ctrl + c 时,我希望以下脚本能够打印This is redirected to 'output'.

#!/bin/bash

trap_function(){
    trap '' EXIT INT TERM
    echo "This is redirected to 'output'."
    touch this_will_exist
}
trap trap_function EXIT INT TERM

eval "sleep 100" &> output

相反,什么也不显示,文本进入文件output。如何从trap_function内部转义重定向,并向用户显示文本?

echo "This is redirected to 'output'." > /dev/stdout效果不理想。

我在Ubuntu 16.04.5 LTS中运行GNU bash版本4.3.48。

2 个答案:

答案 0 :(得分:0)

一种解决方法是让eval在子shell中运行:

#!/bin/bash

trap_function(){
    trap '' EXIT INT TERM
    echo "This is redirected to 'output'."
    touch this_will_exist
}
trap trap_function EXIT INT TERM

(eval "sleep 100") &> output

答案 1 :(得分:0)

要了解发生了什么,必须知道,为了让bash打印发送到stdout的所有内容(即文件描述符1),它将文件描述符1设置为当前终端。 https://catonmat.net/bash-one-liners-explained-part-three对此进行了很好的解释。

&> output用文件output替换文件描述符1和2中的终端。因此,没有echo "..."可以发送给终端的文件描述符。因此,我们有两种可能的解决方案:

重定向到当前终端

这与实用程序tty一起使用,该实用程序返回当前用户终端。

#!/bin/bash

trap_function(){
    trap '' EXIT INT TERM
    echo "This is redirected to 'output'." &>$(tty)
    touch this_will_exist
}
trap trap_function EXIT INT TERM

eval "sleep 100" &> output

但是,可能无法使用包装器捕获此输出。

重定向到另一个文件描述符

此解决方案要求将其他文件描述符设置为当前终端(例如123)。我们可以简单地使用文件描述符1中已设置的内容,然后再用output将其替换为123>&1。然后我们可以将echo的文件描述符(stdout)设置为我们存储在文件描述符123中的文件:

#!/bin/bash

trap_function(){
    trap '' EXIT INT TERM
    echo "This is redirected to 'output'." >&123
    touch this_will_exist
}
trap trap_function EXIT INT TERM

eval "sleep 100" 123>&1 &> output