Предотвратить расширение \ c в аргументе эха - PullRequest
3 голосов
/ 26 мая 2020

Я создаю сценарий оболочки с помощью echo. У меня есть что-то вроде:

echo "sed -i \"\\|charlie\.url\\s*=\\s*.*|c\\charlie.url = ${CHARLIE_URL}\" foo.conf" >> bar.sh

т.е. замените строку в foo.conf , содержащую текущий charl ie .url (не обязательно в начале, потому что строка может быть прокомментирована) для новой строки с новым URL-адресом.

Я бы ожидал, что вывод будет bar. sh будет

sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}" foo.conf

Тем не менее, c\\charlie интерпретируется как c \c harlie вместо c\ charlie, которое генерирует следующий вывод:

sed -i "\|charlie\.url\s*=\s*.*|c

Я обнаружил, что могу предотвратить это, используя одинарные вместо двойных кавычек, но в этом случае ${CHARLIE_URL} (которое мне нужно расширить) не расширяется.

Как должен выглядеть мой аргумент эха?

Я использую da sh (#! / Bin / sh в Ubuntu), но я также могу использовать bash или zsh.

Ответы [ 3 ]

2 голосов
/ 26 мая 2020

Вместо echo можно попробовать cat:

cat << EOF >> bar.sh
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}" foo.conf
EOF
0 голосов
/ 27 мая 2020

Командная строка использует ваш первый sla sh, чтобы процитировать ваш второй. Если CHARLIE_URL=foo, ваше эхо фактически выводит

sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = foo" foo.conf

Попробуйте использовать одинарные кавычки, но закройте / откройте их вокруг переменной.

echo 'sed -i "\\|charlie\.url\\s*=\\s*.*|c\\charlie.url = '"${CHARLIE_URL}"'" foo.conf'

Это даст

sed -i "\\|charlie\.url\\s*=\\s*.*|c\\charlie.url = foo" foo.conf

Вы также можете, как уже упоминалось, процитировать sla sh, который цитирует sla sh, а затем цитировать sla sh, цитируемый другим sla sh, чтобы последующие итерации свели их к тому, что вы хотите ... но это, как правило, беспорядок и приводит к синдрому зубочистки.

Кто-то уже сделал хорошее предложение c, так что я не буду повторять это, но вы также можно использовать "здесь строку", которую я обычно предпочитаю.

cat <<< "sed -i '\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}' foo.conf"

Я переключил двойные кавычки в вашем скрипте на одиночные, предполагая, что вы хотите вывести буквальное значение $ CHARLIE_URL в ваш скрипт . Если вы хотите, чтобы сценарий использовал переменную с любым значением, присвоенным во время выполнения, укажите это тоже -

cat <<< "sed -i '\|charlie\.url\s*=\s*.*|c\charlie.url = \${CHARLIE_URL}' foo.conf"
0 голосов
/ 27 мая 2020
#!/bin/bash

# bash will expand content within "" and stuff like $URL gets expanded
# also double-backslash reduces to a single; bash wouldn't expand stuff within ''

URL="https..."
echo double: "c\\charlie.url, URL $URL"
echo single: 'c\\charlie.url, URL $URL'

# if you need to output a \\
echo "\\\\"
...