Bash将stderr捕获到变量而不重定向

时间:2014-01-31 20:20:45

标签: bash variables stderr

具体来说,我正在编写一个脚本,以便更容易编译和运行我的C ++代码。它很容易判断编译是否成功失败,但我还想添加一个“用警告编译”的状态。

$out    # to avoid an "ambiguous redirect"
g++ -Wall -Wextra $1 2> out

if [ $? == 0 ]
then

        # this is supposed to test the length of the output string
        # unless there are errors, $out should be length 0
    if  [ ${#out} == 0 ]
    then
        # print "Successful"
    else
        # print "Completed with Warnings"
    fi

else
    # print "Failed"
fi

实际上,失败案例检查工作正常,但$out始终为空字符串,但stderr不再显示在屏幕上,$out从未实际设置。如果可能的话,我也希望stderr仍然可以进入屏幕。

我希望我所说的有道理。欢呼声。

2 个答案:

答案 0 :(得分:0)

要捕获变量并在屏幕上显示,请使用tee

out=$( g++ -Wall -Wextra "$1" 2>&1 >dev/null | tee /dev/stderr )

这会抛出g++的标准输出,并将标准错误重定向到标准输出。该输出通过管道传送到tee,将其写入命名文件(/dev/stderr,以便消息返回到原始标准错误)和标准输出,该变量在变量{{1 }}

答案 1 :(得分:0)

g++ -Wall -Wextra $1 2> out

这会将stderr重定向到名为out的文件,而不是名为$out的变量。

如果要运行gcc并在屏幕上看到stdout和stderr以及保存stderr的输出,可以使用命名管道(FIFO)。这有点迂回,但它已经完成了工作。

mkfifo stderr.fifo
gcc -Wall -o /dev/null /tmp/warn.c 2> stderr.fifo &
tee stderr.log < stderr.fifo >&2
rm -f stderr.fifo
wait

运行这些命令后,警告将在stderr.log中提供。利用wait将返回gcc退出代码的事实,您可以执行以下操作:

if wait; then
    if [[ -s stderr.log ]]; then
        # print "Completed with Warnings"
    else
        # print "Successful"
    fi
else
    # print "Failed"
fi

注释:

# Created a named pipe. If one process writes to the pipe, another process can
# read from it to see what was written.
mkfifo stderr.fifo

# Run gcc and redirect its stderr to the pipe. Do it in the background so we can
# read from the pipe in the foreground.
gcc -Wall -o /dev/null /tmp/warn.c 2> stderr.fifo &

# Read from the pipe and write its contents both to the screen (stdout) and to
# the named file (stderr.log).
tee stderr.log < stderr.fifo >&2

# Clean up.
rm -f stderr.fifo

# Wait for gcc to finish and retrieve its exit code. `$?` will be gcc's exit code.
wait