假设我有一个像下面这样的脚本:
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`
但这是丑陋和不必要的。
不幸的是,如果这里没有答案,这就是我要做的。
我希望还有别的办法。
有人有更好的主意吗?
这个问题有很多重复的地方,其中许多都有一个稍微简单的使用场景,您不希望同时捕获stderr、stdout和退出代码。
if result=$(useless.sh 2>&1); then
stdout=$result
else
rc=$?
stderr=$result
fi
适用于常见的场景,在这种场景中,您希望在成功的情况下得到正确的输出,或者在失败的情况下在stderr上得到诊断消息。
注意,shell的控制语句已经检查了$?在引擎盖下;所以任何看起来像
cmd
if [ $? -eq 0 ], then ...
只是一种笨拙的,不常用的说法吗
if cmd; then ...
改进YellowApple的回答:
这是一个Bash函数,用于将stderr捕获到任何变量中
stderr_capture_example.sh:
#!/usr/bin/env bash
# Capture stderr from a command to a variable while maintaining stdout
# @Args:
# $1: The variable name to store the stderr output
# $2: Vararg command and arguments
# @Return:
# The Command's Returnn-Code or 2 if missing arguments
function capture_stderr {
[ $# -lt 2 ] && return 2
local stderr="$1"
shift
{
printf -v "$stderr" '%s' "$({ "$@" 1>&3; } 2>&1)"
} 3>&1
}
# Testing with a call to erroring ls
LANG=C capture_stderr my_stderr ls "$0" ''
printf '\nmy_stderr contains:\n%s' "$my_stderr"
测试:
bash stderr_capture_example.sh
输出:
stderr_capture_example.sh
my_stderr contains:
ls: cannot access '': No such file or directory
此函数可用于捕获返回的对话框命令的选择。