是否有办法从stderr中提取第一行并将其存储到执行函数的shell脚本中的变量?



假设我在脚本中运行一个命令,它在stderr中的第一行是我需要的东西。我用stderr是因为stdout已经被用来传输其他数据了。我仍然需要stderr的其余部分用于用户反馈,所以我仍然希望显示第一行之后的所有内容。

cmd() {
ssh usr@remote.machine.com '
printf "stderr data line 1 (important)n" 1>&2
printf "stdout data line 1n"
printf "stderr data line 2n" 1>&2
printf "stdout data line 2n"
printf "stdout data line 3n"
printf "stderr data line 3n" 1>&2'
}
# What sort of shell magic would I need to extract
# only the 1st line of stderr?
cmd > store_stdout_to_this_file ??? read -a first_line_of_stderr
echo "$first_line_of_stderr"

我不能使用管道,因为管道只能管道标准输出,即使我要重新排列它们,那么管道的另一端也在不同的进程空间。

我看到有几种方法可以做到这一点,它们都有不同的限制和奇怪之处。可能最简单的方法是将stderr重定向到运行read一次的后台子shell(通过进程替换),然后再运行cat:

cmd >outputfile 2> >(read firstline; echo "First line is: '$firstline'"; cat -u)

但是这会将第一行处理放在子shell中,因此当该shell退出时,它设置的任何变量都将丢失。我想你可以让它把这行写到另一个文件中,然后从主脚本中读取…

另一种可能性是将您试图捕获的命令放在进程替换中,并将readcat放在主shell中:

{ read firstline; cat -u; } < <(cmd 2>&1 >outputfile)
echo "First line is: '$firstline'"

注意,cmd的输出重定向必须在进程替换部分内完成(因为它的标准输出被发送到read-cat部分),2>&1必须在第一个,这样标准错误就不会到达相同的地方。

你可以这样做:

line=
while read -r; do
[[ -z $line ]] && line="$REPLY" || echo "$REPLY"
done < <(cmd 2>&1 >out.log)
stderr data line 2
stderr data line 3
# check $line
echo "$line"
stderr data line 1 (important)

。将stderr重定向到stdout,然后将stdout重定向到out.log,最后使用head -n 1进行管道输出。

相关内容

  • 没有找到相关文章

最新更新