abc
def
ghi
在另一个脚本中,我称之为: >
,
$RESULT
会得到值declare RESULT=$(./myscript)
用'
echo -e
'输出吗?#1 楼
实际上,RESULT包含您想要的内容-进行演示:echo "$RESULT"
显示的内容是您从中获得的:
如注释中所述,区别在于(1)变量的双引号版本(
echo "$RESULT"
)保留值的内部间距与变量中表示的值完全相同-换行符,制表符,多个空格和所有空格–而(2)未引用版本(echo $RESULT
)用一个空格替换一个或多个空格,制表符和换行符的每个序列。因此,(1)保留输入变量的形状,而(2)创建一个可能很长的单行输出,其中“单词”由单个空格分隔(其中“单词”是非空白字符的序列;需要不能是任何字母数字)。评论
@troelskn:区别在于(1)变量的双引号版本保留值的内部间距,该值与变量,换行符,制表符,多个空格以及所有变量中所表示的值完全相同,而(2)未引用的版本替换一个或多个空格,制表符和换行符的每个序列,并用一个空格隔开。因此,(1)保留输入变量的形状,而(2)创建一个可能很长的单行输出,其中“单词”由单个空格分隔(其中“单词”是非空白字符的序列;需要不能是任何字母数字)。
–乔纳森·莱弗勒(Jonathan Leffler)
2011年4月12日在1:03
为了使答案更易于理解:答案告诉echo“ $ RESULT”保留换行符,而echo $ RESULT则不保留换行符。
–于申
2012年7月14日10:15
在某些情况下,这无法保留换行符和开头的空格。
– ComaToast
16年8月13日在5:51
@CommaToast:您要详细说明吗?尾随换行符丢失;周围没有简单的方法。前导空白-我不知道在任何情况下它们会丢失。
–乔纳森·莱弗勒(Jonathan Leffler)
16年8月13日在6:11
另请参见何时将引号括在shell变量周围?
–tripleee
17年3月13日在9:39
#2 楼
这样做的另一个陷阱是命令替换-$()
-删除尾随的换行符。可能并不总是很重要,但是如果您真的想保留输出的内容,则必须使用另一行并加上一些引号:如果要处理所有可能的文件名(以避免发生诸如对错误文件进行操作之类的未定义行为)。评论
我不得不用一个坏掉的外壳工作了一段时间,它没有从命令替换中删除最后一个换行符(它不是进程替换),并且它几乎破坏了所有东西。例如,如果您做了pwd =`pwd`; ls $ pwd / $ file,在/之前有换行符,并且用双引号将名称引起来没有帮助。它很快修复。这是在1983-5年ICL Perq PNX上的时间范围; shell没有$ PWD作为内置变量。
–乔纳森·莱弗勒(Jonathan Leffler)
2013年12月29日17:59
#3 楼
如果您对特定的行感兴趣,请使用结果数组:declare RESULT=($(./myscript)) # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"
评论
如果行中有空格,这将计算字段(空格之间的内容)而不是行。
–利亚姆
15年4月15日在14:00
您将使用readarray和进程替换而不是命令替换:readarray -t RESULT <<(./ myscript>。
–chepner
16年1月18日在18:44
#4 楼
除了@ l0b0给出的答案外,我只是需要保持脚本输出的所有尾随换行符并检查脚本的返回码。l0b0的答案的问题是'echo x正在重置$?归零...所以我设法提出了一个非常巧妙的解决方案:
RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"
评论
这很可爱,实际上我有一个用例,我想拥有一个可以接受任意退出代码和可选消息的die()函数,并且我想使用另一个use()函数提供消息,但是换行符不断压扁,希望这可以让我解决这个问题。
–dragon788
18-09-25在22:43
#5 楼
在这里尝试了大多数解决方案之后,我发现最容易的事情是显而易见的-使用临时文件。我不确定要对多行输出进行处理,但是可以使用read逐行处理它。您唯一不能真正做的就是将所有内容轻松地放在相同的变量中,但是对于大多数实际目的,这是更易于处理的方式。./myscript.sh > /tmp/foo
while read line ; do
echo 'whatever you want to do with $line'
done < /tmp/foo
快速修改以使其执行所需的操作:
result=""
./myscript.sh > /tmp/foo
while read line ; do
result="$result$line\n"
done < /tmp/foo
echo -e $result
请注意,这会增加一行。如果您使用它,可以在它周围编写代码,我太懒了。在while循环中输入您的stdin,从而为您提供一个脚本,它将运行一行,清除stdin并退出。像ssh一样,我认为呢?我最近才看到它,这里还有其他代码示例:https://unix.stackexchange.com/questions/24260/reading-lines-from-a-file-with-bash-for-vs-while
再来一次!这次使用不同的文件句柄(stdin,stdout,stderr为0-2,因此我们可以在&bash中使用&3或更高版本)。
,但这只是一个快速的代码示例。 mktemp的用法如下:
result=""
./test>/tmp/foo
while read line <&3; do
result="$result$line\n"
done 3</tmp/foo
echo -e $result
然后像使用文件的实际名称一样使用$ filenamevar。可能不需要在这里解释,但是有人在评论中抱怨。
评论
我也尝试了其他解决方案,根据您的第一个建议,我终于使脚本工作了
– Kar.ma
16年9月9日在15:04
Downvote:这过于复杂,无法避免多个常见的bash陷阱。
–tripleee
17年3月13日在9:39
是的,前几天有人告诉我有关stdin filehandle怪异问题的消息,我就像“哇”。 Lemme很快就添加了一些东西。
–user1279741
17年3月13日在20:21
在Bash中,您可以使用读取命令扩展名-u 3来读取文件描述符3。
–乔纳森·莱弗勒(Jonathan Leffler)
18年8月10日在16:41
除了@JonathanLeffler注释之外,您还可以编写:在读取-ru $ testout行时;回显“使用$ line做某事”;完成{testout} <<(./ test)而不是创建临时文件!
– F. Hauri
10月15日在8:46
#6 楼
解析多个输出简介
,因此您的
myscript
输出3行,可能看起来像:脚本(不需要路径./
),但是输出相同。myscript() { echo $'abc\ndef\nghi'; }
考虑结果代码
要检查结果代码,测试功能将变为:
myscript() { local i; for i in abc def ghi ;do echo $i; done ;}
1。将多个输出存储在一个变量中,显示换行符
您的操作是正确的:
myscript
abc
def
ghi
关于结果代码,您可以添加:
myscript() { local i;for i in abc def ghi ;do echo $i;done;return $((RANDOM%128));}
偶在同一行:
RESULT=$(myscript)
然后
RCODE=$?
,但要显示变量定义,请使用
declare -p
:RESULT=$(myscript) RCODE=$?
2。使用
mapfile
在数组中解析多个输出将答案存储到
myvar
变量中:echo $RESULT
abc def ghi
echo "$RESULT"
abc
def
ghi
echo ${RESULT@Q}
$'abc\ndef\nghi'
printf "%q\n" "$RESULT"
$'abc\ndef\nghi'
显示
$myvar
:declare -p RESULT
declare -- RESULT="abc
def
ghi"
考虑结果代码
如果必须检查结果代码,则可以:
mapfile -t myvar < <(myscript)
echo ${myvar[2]}
ghi
read解析多个输出
declare -p myvar
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")
显示变量:
RESULT=$(myscript) RCODE=$?
mapfile -t myvar <<<"$RESULT"
我经常使用:
{ 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 /)
评论
查看有关帮助阅读和帮助Mapfile的有关换行符,反斜杠和其他特殊功能的选项!
– F. Hauri
10月15日上午10:21
#7 楼
怎么样,它将每行读入一个变量,并且可以随后使用!评论
好吧,那不是bash,那是awk。
–vadipp
13年2月8日在7:29
评论
这让我感到惊讶。您没有$(cat ./myscipt)吗?否则我会期望它尝试执行命令abc,def和ghi@litb:是的,我想是这样;您还可以使用$(<./ myscript)避免执行命令。
(注意:上面的两个注释指的是该问题的修订版,开始时我有一个脚本“ myscript”,其中包含以下内容,从而导致了这些问题。该问题的当前修订版(我有一个脚本“ myscript'(输出以下内容)使注释变得多余,但是,修订是在2011年11月11日发布的,这两个注释已经很久了。