Мне нужно написать сложный xml в переменную внутри сценария bash. Xml должен быть доступен для чтения внутри сценария bash, поскольку именно здесь будет находиться фрагмент xml, который не читается из другого файла или источника.
Итак, мой вопрос: если у меня есть длинная строка, которую я хочу, чтобы человек мог читать внутри моего сценария bash, как лучше всего это сделать?
В идеале хочу:
Можно ли это сделать с помощью EOF или чего-то еще, может ли кто-нибудь привести мне пример?
например
String = <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
Это поместит ваш текст в вашу переменную без необходимости экранировать кавычки. Он также будет обрабатывать несбалансированные кавычки (апострофы, т.е. '
). Заключение в кавычки метки (EOF) предотвращает расширение параметров текста. В -d''
заставляет его читать несколько строк (игнорировать новые строки). read
является встроенным в Bash, поэтому не требует вызова внешней команды, такой как cat
.
IFS='' read -r -d '' String <<"EOF"
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
Вы почти были там. Либо вы используете кошка для сборки вашей строки или вы указываете всю строку (в этом случае вам придется избегать кавычек внутри вашей строки):
#!/bin/sh
VAR1=$(cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
)
VAR2="<?xml version=\"1.0\" encoding='UTF-8'?>
<painting>
<img src=\"madonna.jpg\" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's \"Foligno\" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>"
echo "${VAR1}"
echo "${VAR2}"
#!/bin/sh
VAR1=`cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
`
echo "VAR1: ${VAR1}"
Это должно нормально работать в среде оболочки Bourne.
Мне нравится использовать переменные и специальные <<-
кто падает табулирование в начале каждой строки, чтобы разрешить отступ скрипта:
#!/bin/bash
mapfile Pattern <<-eof
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="%s" alt='%s'/>
<caption>%s, painted in
<date>%s</date>-<date>%s</date>.</caption>
</painting>
eof
while IFS=";" read file alt caption start end ;do
printf "${Pattern[*]}" "$file" "$alt" "$caption" "$start" "$end"
done <<-eof
madonna.jpg;Foligno Madonna, by Raphael;This is Raphael's "Foligno" Madonna;1511;1512
eof
предупреждение: здесь нет пустое пространство перед eof
но только табулирование.
<?xml version="1.0" encoding='UTF-8'?>
<painting>
<img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
<caption>This is Raphael's "Foligno" Madonna, painted in
<date>1511</date>-<date>1512</date>.</caption>
</painting>
Some explanations: "${Pattern[*]}"
преобразовать этот массив в строку.IFS=";"
потому что нет ;
в обязательных строкахwhile IFS=";" read file ...
предотвращать IFS
для изменения остальной части скрипта. В этом только read
использовать модифицированный IFS
.Во многих других ответах слишком много угловых случаев.
Чтобы быть абсолютно уверенным, что нет проблем с пробелами, табуляциями, IFS и т. Д., Лучше использовать конструкцию "heredoc", но кодировать содержимое heredoc с помощью uuencode
как объяснено здесь: