假设我有一个像下面这样的脚本:
useless.sh
echo "This Is Error" 1>&2
echo "This Is Output"
我有另一个shell脚本:
alsoUseless.sh
./useless.sh | sed 's/Output/Useless/'
我想捕捉“这是错误”,或任何其他stderr从无用的。sh,到一个变量。
我们称它为ERROR。
注意,我使用了stdout。我想继续使用stdout,所以在这种情况下,将stderr重定向到stdout没有帮助。
所以,基本上,我想做
./useless.sh 2> $ERROR | ...
但这显然行不通。
我也知道我能做到
./useless.sh 2> /tmp/Error
ERROR=`cat /tmp/Error`
但这是丑陋和不必要的。
不幸的是,如果这里没有答案,这就是我要做的。
我希望还有别的办法。
有人有更好的主意吗?
重复Tom Hale的回答,我发现可以将重定向瑜伽包装到一个函数中,以便于重用。例如:
#!/bin/sh
capture () {
{ captured=$( { { "$@" ; } 1>&3 ; } 2>&1); } 3>&1
}
# Example usage; capturing dialog's output without resorting to temp files
# was what motivated me to search for this particular SO question
capture dialog --menu "Pick one!" 0 0 0 \
"FOO" "Foo" \
"BAR" "Bar" \
"BAZ" "Baz"
choice=$captured
clear; echo $choice
几乎可以肯定,可以进一步简化。还没有进行特别彻底的测试,但它似乎可以同时使用bash和ksh。
EDIT:捕获函数的另一个版本,它将捕获的STDERR输出存储到用户指定的变量中(而不是依赖于全局$ capturing),灵感来自Léa Gris的答案,同时保留了上述实现的ksh(和zsh)兼容性:
capture () {
if [ "$#" -lt 2 ]; then
echo "Usage: capture varname command [arg ...]"
return 1
fi
typeset var captured; captured="$1"; shift
{ read $captured <<<$( { { "$@" ; } 1>&3 ; } 2>&1); } 3>&1
}
和用法:
capture choice dialog --menu "Pick one!" 0 0 0 \
"FOO" "Foo" \
"BAR" "Bar" \
"BAZ" "Baz"
clear; echo $choice