将stdout和stderr捕获到不同的变量中

是否可以在不使用临时文件的情况下在不同的变量中存储或捕获stdout和stderr ?现在我这样做是为了out在err运行时获取stdout 和stderr some_command,但是我想避开临时文件。


error_file=$(mktemp)

out=$(some_command 2>$error_file)

err=$(< error_file)

rm $error_file


HUX布斯
浏览 838回答 3
3回答

函数式编程

好吧,它有点难看,但这是一个解决方案:unset t_std t_erreval "$( (echo std; echo err >&2) \&nbsp; &nbsp; &nbsp; &nbsp; 2> >(readarray -t t_err; typeset -p t_err) \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;> >(readarray -t t_std; typeset -p t_std) )"其中(echo std; echo err >&2)需要通过实际的命令来代替。的输出标准输出被保存到数组中$t_std由线省略换行符(线-t)和标准错误入$t_err。如果你不喜欢数组,你可以做unset t_std t_erreval "$( (echo std; echo err >&2 ) \&nbsp; &nbsp; &nbsp; &nbsp; 2> >(t_err=$(cat); typeset -p t_err) \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;> >(t_std=$(cat); typeset -p t_std) )"它几乎模仿了var=$(cmd)除了$?我们最后一次修改的值之外的行为:unset t_std t_err t_reteval "$( (echo std; echo err >&2; exit 2 ) \&nbsp; &nbsp; &nbsp; &nbsp; 2> >(t_err=$(cat); typeset -p t_err) \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;> >(t_std=$(cat); typeset -p t_std); t_ret=$?; typeset -p t_ret )"这里$?保存成$t_ret使用GNU bash,版本4.2.37(1)-release(i486-pc-linux-gnu)在Debian wheezy上测试。

开满天机

作为参考,这是ksh93技巧。(需要非古代版本)。function out {    echo stdout    echo stderr >&2}x=${ { y=$(out); } 2>&1; }typeset -p x y # Show the values产生x=stderry=stdout该${ cmds;}语法只是一个命令替换不创建一个子shell。这些命令在当前的shell环境中执行。开头的空间很重要({是一个保留字)。内部命令组的Stderr被重定向到stdout(因此它适用于内部替换)。接下来,stdout out被分配给y,并且重定向的stderr被捕获x,而没有通常丢失y到命令替换的子shell。在其他shell中是不可能的,因为捕获输出的所有构造都需要将生成器放入子shell中,在这种情况下,它将包括赋值。更新:现在也受mksh支持。

汪汪一只猫

此命令在当前运行的shell中设置stdout(stdval)和stderr(errval)值:eval "$( execcommand 2> >(setval errval) > >(setval stdval); )"如果已定义此功能:function setval { printf -v "$1" "%s" "$(cat)"; declare -p "$1"; }将execcommand更改为捕获的命令,无论是“ls”,“cp”,“df”等。所有这些都是基于我们可以在函数setval的帮助下将所有捕获的值转换为文本行的想法,然后setval用于捕获此结构中的每个值:execcommand 2> CaptureErr > CaptureOut将每个捕获值转换为setval调用:execcommand 2> >(setval errval) > >(setval stdval)将所有内容包装在执行调用中并回显它:echo "$( execcommand 2> >(setval errval) > >(setval stdval) )"您将获得每个setval创建的声明调用:declare -- stdval="I'm std"declare -- errval="I'm err"要执行该代码(并设置vars),请使用eval:eval "$( execcommand 2> >(setval errval) > >(setval stdval) )"最后回应设置的变量:echo "std out is : |$stdval| std err is : |$errval|还可以包括return(exit)值。完整的bash脚本示例如下所示:#!/bin/bash --# The only function to declare:function setval { printf -v "$1" "%s" "$(cat)"; declare -p "$1"; }# a dummy function with some example values:function dummy { echo "I'm std"; echo "I'm err" >&2; return 34; }# Running a command to capture all values#&nbsp; &nbsp; &nbsp; change execcommand to dummy or any other command to test.eval "$( dummy 2> >(setval errval) > >(setval stdval); <<<"$?" setval retval; )"echo "std out is : |$stdval| std err is : |$errval| return val is : |$retval|"
打开App,查看更多内容
随时随地看视频慕课网APP