如何通过命令传输此处文档并将结果捕获到变量中?

发布于 2024-08-18 14:58:48 字数 472 浏览 4 评论 0原文

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

要求:

  • 脚本必须全部位于一个文件中。
  • 如果可能的话,我不想写任何临时文件。

#!/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

Right now this outputs the value I need on stdout. How can I capture it into a variable so I can use it in the rest of the script?

Requirements:

  • The script needs to be all in one file.
  • I'd prefer not to write any temp files, if possible.

.

#!/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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眼中杀气 2024-08-25 14:58:48

cat ... | 不是必需的。

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

The cat ... | isn't necessary.

foo=$(sed 's/-/_/g' << EOF
1-2
3-4
EOF
)
香草可樂 2024-08-25 14:58:48

这似乎有效(基于伊格纳西奥的回答)。通过使用子 shell,此处文档可以正确地通过管道传输到 xsltproc,同时仍然通过 tail 传递。

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
)

This seems to work (based on Ignacio's answer). By using a subshell the here-document is correctly piped into xsltproc while still being passed through 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
)
指尖凝香 2024-08-25 14:58:48

我已经研究了 heredocs 一两周了。这是我对 Is there a way to get actual (uninterpreted) shell argument in a 的回答的摘录函数或脚本? 在 Unix Stack Exchange 上,这可能有助于说明它们在您的情况下的用法:

...
摘录:
...

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

您可能想要做的是将 Windows 路径从一个命令的输出动态地传递到另一个命令的输入。 定界文档中的命令替换使这成为可能:

% _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),那么在 $(...) 中运行该命令并将其包含在传递给另一个应用程序的未加引号的定界文档中可以可靠地接受反斜杠作为输入(例如上面的 read 和 sed)将完全绕过 shell 对反斜杠的解析。应用程序是否可以将反斜杠作为输入/输出处理,您必须自己找出答案。

-麦克风

I've been playing around with heredocs for a week or two. Here's an excerpt from my answer to Is there a way to get actual (uninterpreted) shell arguments in a function or script? at Unix Stack Exchange that might help illustrate their use a little for your case:

...
EXCERPT:
...

Probably you noticed the difference between the two heredocs in the second example. The heredoc EOF terminator within the function is unquoted, while the one fed to read is quoted with single quotes. In this way the shell is instructed to perform expansion on the heredoc with an unquoted terminator, but not to do so when its terminator is quoted. It doesn't break when expanding the unquoted heredoc in the function because the value of the variable it expands is already set as a quoted string and it doesn't parse it twice.

Probably what you want to do involves piping your Windows path from the output of one command into the input of another dynamically. Command substitution within a heredoc makes this possible:

% _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

So basically if you can reliably output the backslashes from some application (I used printf above), then running that command within $(...) and enclosing that within an unquoted heredoc passed to another application that can reliably accept the backslashes as input (such as read and sed above) will bypass the shell's parsing of your backslashes altogether. Whether or not the applications can handle the backslashes as input/output is something you'll have to find out for yourself.

-Mike

愿与i 2024-08-25 14:58:48

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

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
)

You don't need the tail -1 by adding 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
)
冷血 2024-08-25 14:58:48

与马克的答案类似,使用子外壳,此处将所有文档放置在管道之前也将起作用:

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)

Similar to Mark's answer, with the sub-shell, here document placing all before pipe will also work:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文