Як надрукувати "$" у цьому документі


42

Як я можу відлунювати "$" у here-doc в bash?

Наприклад, я хочу мати файл із вмістом на віддаленому сервері, як $ABC=home_dir.

$ ssh hostname sudo -s <<EOF
echo "$ABC=home_dir" > file
EOF

Але це трактується як змінна. Як я можу надрукувати літерал $?


2
Ви можете використовувати одинарні цитати
Рахул Патіль

2
Це багато непрямого відбувається. Ви впевнені, що не можете створити файл на локальному хості, а потім scpйого?
l0b0

Відповіді:


65

Якщо ви хочете написати тут-doc, і ви не хочете, щоб будь-який документ розширювався або будь-які спеціальні символи були інтерпретовані, ви можете процитувати мітку одинарними цитатами, наприклад:

$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF

Однак ваша ситуація, описана у вашому прикладі, набагато складніша, тому що ви дійсно надсилаєте цей вміст через ssh, у віддалену систему, щоб запускати sudo, який також викликає оболонку (і щоб оболонка розширила вміст так само). Вам знадобиться більше рівнів цитування, щоб отримати це право, але навіть при цьому воно все одно не буде працювати, оскільки для sudo потрібен термінал (щоб він міг запитати пароль), і ви перенаправилися з stdin. Навіть використання ssh -tтут не допоможе.

Також я згоден з Йоханом. Не ясно, що це дійсно те, чого ти хочеш; зауважте, що присвоювати значення посиланню на змінну оболонки неправомірно, тому якщо цей файл, який ви намагаєтеся створити, повинен бути сценарієм оболонки, він не працюватиме так, як ви його описали. Можливо, якщо ви трохи зробите резервну копію і опишіть, що ви дійсно хочете зробити, ми можемо допомогти більше.


Це найкраща відповідь, оскільки вона може задовольнити дуже довгі документи ТУТ. Це (в основному) ідіот-доказ.
Феліпе Альварес

22

Втеча $

$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF

Я не знаю, що стосується вашої справи, але зазвичай ви хочете home_dir=$ABCзамість цього $ABC=home_dir.


2
Це рішення спрацює, але чи справді те, чого хоче ОП? Схоже, генерується скрипт оболонки, який при виконанні зберігатиме у "файлі" рядок, яка відмежує ABC для лівої частини призначення і, ймовірно, в кінцевому підсумку зберігає =home_dirу файл? Звичайно, я не знаю, в чому справа використання ...
Йохан

2
Це призведе до того, що буквал $буде надісланий до віддаленої оболонки, але тоді ця оболонка буде розгорнута, $ABCперш ніж повторювати рядок до file. Щоб записати буквально $у файл, вам знадобиться інший (уникнутий) ривок:, echo "\\\$ABC=home_dir"щоб отримати віддалений оболонку echo "\$ABC=home_dir".
чепнер

9

Найдешевшим був би спосіб втечі

$ ssh hostname sudo -s << \EOF
echo "$ABC=home_dir" > file
EOF

4

Ви заощадите рівень цитування, відправивши рядок в catпроцес на віддаленому кінці:

echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"

Одиничні лапки захищають $локальний кінець, а оболонка ніколи не бачиться оболонкою, оскільки вона читається безпосередньо cat(через sudo), а не є аргументом для іншої команди оболонки.

За допомогою свого коду вам знадобиться додатковий шар для втечі для захисту $:

$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF

Вам потрібно надіслати літерал \$на віддалений хост, щоб віддалена оболонка записала буква $в файл. Ви також можете спростити це, цитуючи маркер here-doc:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.