我最近发现了一些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}}不会 在文件中。
答案 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