如何通过命令管理here-document并将结果捕获到变量中?

时间:2010-01-24 21:30:56

标签: bash shell heredoc

现在,这将输出我在stdout上需要的值。如何将其捕获到变量中,以便我可以在脚本的其余部分中使用它?

要求:

  • 脚本需要全部在一个文件中。
  • 如果可能的话,我不想写任何临时文件。

#!/bin/bash

cat << EOF | xsltproc - ../pom.xml | tail -1
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/"><xsl:value-of select="/project/version"/></xsl:template>
</xsl:stylesheet>
EOF

3 个答案:

答案 0 :(得分:12)

cat ... |不是必需的。

foo=$(sed 's/-/_/g' << EOF
1-2
3-4
EOF
)

答案 1 :(得分:12)

这似乎有效(基于Ignacio的回答)。通过使用子shell,here-document被正确地传送到xsltproc,同时仍然通过尾部传递。

VERSION=$((xsltproc - ../pom.xml | tail -1) << EOF
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/"><xsl:value-of select="/project/version"/></xsl:template>
</xsl:stylesheet>
EOF
)

答案 2 :(得分:2)

我已经和heredocs玩了一两个星期。以下是我在Unix Stack Exchange上对Is there a way to get actual (uninterpreted) shell arguments in a function or script?的回答摘录,可能有助于说明它们对您的使用有一点用处:

... 的摘录: ...

可能你注意到第二个例子中两个heredoc之间的区别。函数中的heredoc EOF 终止符是不带引号的,而用于读取的单引号引用了一个。通过这种方式,shell被指示使用不带引号的终结符对heredoc执行扩展,但是当引用其终结符时不执行此操作。在函数中扩展未引用的heredoc时它不会中断,因为它展开的变量的值已经设置为带引号的字符串,并且它不会解析它两次。

您可能想要做的事情涉及将Windows路径从一个命令的输出流动到另一个命令的输入中。 heredoc中的命令替换使这成为可能:

% _stupid_mspath_fix() { 
> sed -e 's@\\@/@g' -e 's@\(.\):\(.*\)@/drive/\1\2@' <<_EOF_
>> ${1}
>> _EOF_
> }
% read -r _stupid_mspath_arg <<'_EOF_'                    
> c:\some\stupid\windows\place
> _EOF_
% _stupid_mspath_fix ${_stupid_mspath_arg}
/drive/c/some/stupid/windows/place    
% read -r _second_stupid_mspath_arg <<_EOF_                    
> $(printf ${_stupid_mspath_arg})
> _EOF_
% _stupid_mspath_fix ${_second_stupid_mspath_arg}
/drive/c/some/stupid/windows/place

所以基本上如果你能从一些应用程序(我上面使用printf)可靠地输出反斜杠,然后在$(...)中运行该命令并将其包含在一个不带引号的heredoc中,传递给另一个能够可靠地接受反斜杠的应用程序作为输入(例如上面的read和sed)将绕过shell对反斜杠的解析。应用程序是否可以处理反斜杠作为输入/输出是你必须自己找到的东西。

-Mike