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

utugiqy6  于 2023-08-07  发布在  Shell
关注(0)|答案(5)|浏览(106)

现在它输出了我需要的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

字符串

wz8daaqr

wz8daaqr1#

cat ... |不是必需的。

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

字符串

euoag5mw

euoag5mw2#

这似乎是可行的(根据伊格纳西奥的回答)。通过使用一个子shell,here-document被正确地通过管道传输到xsltproc,同时仍然通过tail after传递。

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
)

字符串

h7appiyu

h7appiyu3#

我已经用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对你的反斜杠的解析。应用程序是否可以将反斜杠作为输入/输出来处理,这需要您自己去弄清楚。

  • 麦克
zxlwwiss

zxlwwiss4#

你不需要tail -1通过添加omit-xml-declaration="yes"

VERSION=$(xsltproc - pom.xml << EOF
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mvn="http://maven.apache.org/POM/4.0.0">
<xsl:output method="text" omit-xml-declaration="yes"/>
<xsl:template match="/"><xsl:value-of select="mvn:project/mvn:version"/></xsl:template>
</xsl:stylesheet>
EOF
)

字符串

nxagd54h

nxagd54h5#

与Mark的答案类似,使用子shell,在这里文档放置所有管道之前也可以工作:

VERSION=$((xsltproc - ../pom.xml << 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
) | tail -1)

字符串

相关问题