Min*_*nix 5 bash io-redirection shell-script
我正在尝试向我的脚本添加调试选项。通常我想隐藏任何输出,比如警告等,所以我把>/dev/null 2>&1很多命令放在后面。
现在,当我想调试我的脚本时,我必须手动删除它们,或者将每个命令放在if ... fi一个$DEBUG变量的测试中。
我认为放入>/dev/null 2>&1一个变量 ( $REDIR) 并写入command arg1 $REDIR可以解决问题。如果我想调试,我只需要$REDIR留空。
但是在我的 shell 上的一个简短测试告诉我,它不会那样工作:
~$ echo "bla" >/dev/null 2>&1
~$ REDIR=>/dev/null 2>&1
~$ echo "bla" $REDIR
bla
~$
Run Code Online (Sandbox Code Playgroud)
由于明显的原因,使用"或'周围>/dev/null 2>&1也不起作用。
那么为什么我的想法在这里不起作用?我是否误解了将命令等放入变量并调用它们的内容?
重定向不是命令,因此您不能以这种方式执行它。如果您使用eval,您可以完成它,但这是打开一罐蠕虫。
一个更好的方法来做你想做的事情是有一个调试输出的功能:
function debugprint {
if [ ! -z "$debug" ]; then
echo "$1"
fi
}
debugprint "$(echo 'bla' 2>&1)"
Run Code Online (Sandbox Code Playgroud)
这会将标准错误重定向到标准输出,然后debugprint将输出作为参数调用。现在您需要做的就是$debug在要调试时将其设置为非空。
当然,这也打开了一个(不同的)蠕虫罐头(与引用有关)。您可能只想使用set -x它,这可能会也可能不足以满足您的调试需求。
出于这样的目的,我通常定义一个类似 的函数run。在大多数情况下,这可以正确处理带有空格和其他参数的参数。
#!/bin/bash
run() {
if $DEBUG; then
v=$(exec 2>&1 && set -x && set -- "$@")
echo "#${v#*--}"
"$@"
else
"$@" >/dev/null 2>&1
fi
}
DEBUG=false
run echo "bla"
DEBUG=true
run echo "bla"
run printf "%s . %s . %s\n" bla "more bla" bla
Run Code Online (Sandbox Code Playgroud)
输出:
$ bash debug.sh
# echo bla
bla
# printf '%s . %s . %s\n' bla 'more bla' bla
bla . more bla . bla
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2672 次 |
| 最近记录: |