我有一个脚本'myscript',输出如下:

abc
def
ghi

在另一个脚本中,我调用:

declare RESULT=$(./myscript)

$RESULT获取值

abc def ghi

是否有一种方法来存储结果与换行符,或与'\n'字符,所以我可以输出它与'echo -e'?


当前回答

除了@l0b0给出的答案之外,我还遇到了这样的情况:我需要保留脚本输出的任何尾随换行符,并检查脚本的返回代码。 和l0b0的答案的问题是'echo x'重置$?回到零…所以我想出了这个非常狡猾的解决方案:

RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"

其他回答

实际上,RESULT包含了您想要演示的内容:

echo "$RESULT"

你所展示的就是你所得到的:

echo $RESULT

As noted in the comments, the difference is that (1) the double-quoted version of the variable (echo "$RESULT") preserves internal spacing of the value exactly as it is represented in the variable — newlines, tabs, multiple blanks and all — whereas (2) the unquoted version (echo $RESULT) replaces each sequence of one or more blanks, tabs and newlines with a single space. Thus (1) preserves the shape of the input variable, whereas (2) creates a potentially very long single line of output with 'words' separated by single spaces (where a 'word' is a sequence of non-whitespace characters; there needn't be any alphanumerics in any of the words).

除了@l0b0给出的答案之外,我还遇到了这样的情况:我需要保留脚本输出的任何尾随换行符,并检查脚本的返回代码。 和l0b0的答案的问题是'echo x'重置$?回到零…所以我想出了这个非常狡猾的解决方案:

RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"

这样做的另一个缺陷是命令替换- $()-删除尾随换行符。可能并不总是重要的,但如果你真的想保留输出的内容,你必须使用另一行和一些引用:

RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"

如果您想处理所有可能的文件名(以避免在错误的文件上操作等未定义的行为),这一点尤其重要。

解析多个输出

介绍

你的myscript输出3行,看起来像这样:

myscript() { echo $'abc\ndef\nghi'; }

or

myscript() { local i; for i in abc def ghi ;do echo $i; done ;}

好吧,这是一个函数,不是一个脚本(不需要路径。/),但输出是一样的

myscript
abc
def
ghi

考虑结果代码

为了检查结果代码,test函数将变成:

myscript() { local i;for i in abc def ghi ;do echo $i;done;return $((RANDOM%128));}

1. 在一个变量中存储多个输出,显示换行

操作正确:

RESULT=$(myscript)

关于结果代码,您可以添加:

RCODE=$?

即使在同一行:

RESULT=$(myscript) RCODE=$?

Then

echo $RESULT $RCODE
abc def ghi 66
echo "$RESULT"
abc
def
ghi
echo ${RESULT@Q}
$'abc\ndef\nghi'
printf '%q\n' "$RESULT"
$'abc\ndef\nghi'

但要显示变量定义,请使用declare -p:

declare -p RESULT RCODE
declare -- RESULT="abc
def
ghi"
declare -- RCODE="66"

2. 使用mapfile解析数组中的多个输出

将答案存储到myvar变量:

mapfile -t myvar < <(myscript)
echo ${myvar[2]}
ghi

显示$ myvar:

declare -p myvar
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")

考虑结果代码

如果你必须检查结果代码,你可以:

RESULT=$(myscript) RCODE=$?
mapfile -t myvar <<<"$RESULT"

declare -p myvar RCODE
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")
declare -- RCODE="40"

3.通过命令组中的连续读取来解析多个输出

{ read firstline; read secondline; read thirdline;} < <(myscript)
echo $secondline
def

显示变量:

declare -p firstline secondline thirdline
declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"

我经常使用:

{ read foo;read foo total use free foo ;} < <(df -k /)

Then

declare -p use free total
declare -- use="843476"
declare -- free="582128"
declare -- total="1515376"

考虑结果代码

同样的前置步骤:

RESULT=$(myscript) RCODE=$?
{ read firstline; read secondline; read thirdline;} <<<"$RESULT"

declare -p firstline secondline thirdline RCODE
declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"
declare -- RCODE="50"

如果你对特定的行感兴趣,使用result-array:

declare RESULT=($(./myscript))  # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"