Как передать документ here-document через команду и записать результат в переменную?


Прямо сейчас это выводит значение, которое мне нужно на 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 15

3 ответа:

В cat ... | нет необходимости.

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

Это, кажется, работает (на основе ответа Игнасио). С помощью подрешетки here-документ корректно передается в 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
)

Я играю с heredocs уже неделю или две. Вот отрывок из моего ответа на Есть ли способ получить фактические (неинтерпретированные) аргументы оболочки в функции или скрипте? в Unix Stack Exchange, что может помочь немного проиллюстрировать их использование для вашего случая:

... отрывок: ...

Вероятно, вы заметили разницу между двумя heredoc во втором примере. Терминатор heredoc EOF внутри функции не имеет кавычек, в то время как тот, кого кормят читать, цитируется с одинарными кавычками. Таким образом, оболочка получает инструкции выполнять расширение на 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 выше), будет полностью обходить синтаксический анализ оболочки ваших обратных косых черт. Могут ли приложения или нет обрабатывать обратную косую черту как вход / выход-это то, что вы должны будете выяснить для себя.

- Майк