如何在bash中覆盖函数重定向?

时间:2013-07-29 07:43:23

标签: bash function io-redirection

我最近发现了一些bash代码,这些代码使用了鲜为人知的(很好,很少知道 me )功能重定向的功能,例如大大简化:

function xyzzy () {
    echo hello
} >/dev/null

当您使用简单的xyzzy调用该函数时,它会自动应用附加到函数的重定向,无论您在调用它时执行了什么操作。

我想知道的是,在调用函数本身时是否有任何方法可以覆盖此行为,以查看正在生成的消息。我很谨慎地改变包含所有函数的文件,因为(1)它很大,(2)它经常变化,(3)它受到支持它的组的严密保护。

我试过了:

xyzzy >&1

尝试覆盖它,但输出仍未显示(可能因为>&1可能被视为无操作)。


换句话说,给定脚本:

function xyzzy () {
    echo hello
} >/tmp/junk

rm -f /tmp/junk
echo ================
echo Standard output
echo ----------------
xyzzy # something else here
echo ================
echo Function capture
echo ----------------
cat /tmp/junk
echo ================

目前输出:

================
Standard output
----------------
================
Function capture
----------------
hello
================

我可以更改xyzzy调用,以便在标准输出部分而不是函数捕获部分中打印hello

由于实际的重定向可能是/tmp/junk,因此实际的重定向可能是/dev/null,因此需要 创建文件之后尝试读取文件{{1}}不会 在文件中。

2 个答案:

答案 0 :(得分:2)

我能想到的唯一想法是解析declare -f function_name的输出并删除重定向。

这可能是最简单的方法。请注意,您需要将awk脚本定制为特定的功能布局,并且它根本不会修改函数体。这意味着您只能在顶层关闭重定向。您可以修改函数的整个调用树以关闭重定向,但这需要bash解析器能够识别和更改正文中的函数调用。

以下脚本显示了如何使用示例函数执行此操作。所有awk命令都会创建一个新函数my_xyzzy,它反映xyzzy函数,除了最后一行,有效地将其转换为:

function my_xyzzy () {
    echo hello
}

按照规范完整的脚本:

function xyzzy () {
    echo hello
} >/tmp/qqqq

declare -f xyzzy | awk '
    NR==1 {print "my_xyzzy ()"}
    NR==2 {prev=$0}
    NR>2  {print prev;prev=$0}
    END   {print "}"}' >$$.bash
. $$.bash
rm -f $$.bash

rm -f /tmp/qqqq
echo ================
echo Standard output
echo ----------------
my_xyzzy
echo ================
echo Function capture
echo ----------------
cat /tmp/qqqq
echo ================

输出是:

================
Standard output
----------------
hello
================
Function capture
----------------
cat: /tmp/qqqq: No such file or directory
================

答案 1 :(得分:0)

我不认为Bash函数重定向可以在对函数本身的调用中被重写动态,尽管通过组合Bash aliases和{可以使用临时更改的shell上下文{1}}(见Magic Aliases: A Layering Loophole in the Bourne Shell)。

非动态地,它是最后一个重定向表达式,i。即最右边的一个,如果重定向表达式引用相同的文件描述符,则覆盖前面的那些。

functions

因此,glenn jackman建议使用# example ls -ld / no_such_file 1>/dev/null 1>/dev/tty 1>&2 1>redirtest.txt cat redirtest.txt 似乎是添加最终declare -f function_name重定向表达式以覆盖之前的重定向表达式的方法。

stdout