How to pipe a here-document through a command and capture the result into a variable?

不问归期 提交于 2019-12-04 08:24:35

问题


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

回答1:


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
)



回答2:


The cat ... | isn't necessary.

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



回答3:


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



来源:https://stackoverflow.com/questions/2128949/how-to-pipe-a-here-document-through-a-command-and-capture-the-result-into-a-vari

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!