3 回答

TA貢獻(xiàn)1807條經(jīng)驗(yàn) 獲得超9個(gè)贊
好吧,它有點(diǎn)難看,但這是一個(gè)解決方案:
unset t_std t_err
eval "$( (echo std; echo err >&2) \
2> >(readarray -t t_err; typeset -p t_err) \
> >(readarray -t t_std; typeset -p t_std) )"
其中(echo std; echo err >&2)需要通過(guò)實(shí)際的命令來(lái)代替。的輸出標(biāo)準(zhǔn)輸出被保存到數(shù)組中$t_std由線省略換行符(線-t)和標(biāo)準(zhǔn)錯(cuò)誤入$t_err。
如果你不喜歡數(shù)組,你可以做
unset t_std t_err
eval "$( (echo std; echo err >&2 ) \
2> >(t_err=$(cat); typeset -p t_err) \
> >(t_std=$(cat); typeset -p t_std) )"
它幾乎模仿了var=$(cmd)除了$?我們最后一次修改的值之外的行為:
unset t_std t_err t_ret
eval "$( (echo std; echo err >&2; exit 2 ) \
2> >(t_err=$(cat); typeset -p t_err) \
> >(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上測(cè)試。

TA貢獻(xiàn)1786條經(jīng)驗(yàn) 獲得超13個(gè)贊
作為參考,這是ksh93技巧。(需要非古代版本)。
function out {
? ? echo stdout
? ? echo stderr >&2
}
x=${ { y=$(out); } 2>&1; }
typeset -p x y # Show the values
產(chǎn)生
x=stderr
y=stdout
該${ cmds;}語(yǔ)法只是一個(gè)命令替換不創(chuàng)建一個(gè)子shell。這些命令在當(dāng)前的shell環(huán)境中執(zhí)行。開(kāi)頭的空間很重要({是一個(gè)保留字)。
內(nèi)部命令組的Stderr被重定向到stdout(因此它適用于內(nèi)部替換)。接下來(lái),stdout out被分配給y,并且重定向的stderr被捕獲x,而沒(méi)有通常丟失y到命令替換的子shell。
在其他shell中是不可能的,因?yàn)椴东@輸出的所有構(gòu)造都需要將生成器放入子shell中,在這種情況下,它將包括賦值。
更新:現(xiàn)在也受mksh支持。

TA貢獻(xiàn)1898條經(jīng)驗(yàn) 獲得超8個(gè)贊
此命令在當(dāng)前運(yùn)行的shell中設(shè)置stdout(stdval)和stderr(errval)值:
eval "$( execcommand 2> >(setval errval) > >(setval stdval); )"
如果已定義此功能:
function setval { printf -v "$1" "%s" "$(cat)"; declare -p "$1"; }
將execcommand更改為捕獲的命令,無(wú)論是“l(fā)s”,“cp”,“df”等。
所有這些都是基于我們可以在函數(shù)setval的幫助下將所有捕獲的值轉(zhuǎn)換為文本行的想法,然后setval用于捕獲此結(jié)構(gòu)中的每個(gè)值:
execcommand 2> CaptureErr > CaptureOut
將每個(gè)捕獲值轉(zhuǎn)換為setval調(diào)用:
execcommand 2> >(setval errval) > >(setval stdval)
將所有內(nèi)容包裝在執(zhí)行調(diào)用中并回顯它:
echo "$( execcommand 2> >(setval errval) > >(setval stdval) )"
您將獲得每個(gè)setval創(chuàng)建的聲明調(diào)用:
declare -- stdval="I'm std"
declare -- errval="I'm err"
要執(zhí)行該代碼(并設(shè)置vars),請(qǐng)使用eval:
eval "$( execcommand 2> >(setval errval) > >(setval stdval) )"
最后回應(yīng)設(shè)置的變量:
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
# 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|"
添加回答
舉報(bào)