Bash: одинарные кавычки исчезают при добавлении текста в файл

Я пытаюсь добавить многострочный текст, содержащий несколько одинарных кавычек ('), к файлу, который находится на другом компьютере и к которому можно получить доступ только через другого пользователя. Вот мой фрагмент кода:

element_list=("element1" "element2")
for element in ${element_list[@]} 
do

read -r -d '\n' CONTENT << EOM
field1 = on
field2 = '$element'
field3 = '$element-random-text'
EOM

    CONFIG_FILE=/tmp/config.txt
    sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -c 'echo \"$CONTENT\" >> $CONFIG_FILE'"

done

Хотя скрипты выполняются успешно, одинарные кавычки, присутствующие в значениях field2 и field3, исчезают. Вывод, добавленный к файлу, выглядит так:

field1 = on
field2 = element1
field3 = element1-random-text
field1 = on
field2 = element2
field3 = element2-random-text

Я хочу, чтобы эти одинарные кавычки тоже были сброшены в файл. Ожидаемый результат:

field1 = on
field2 = 'element1'
field3 = 'element1-random-text'
field1 = on
field2 = 'element2'
field3 = 'element2-random-text'

Любая помощь будет оценена по достоинству.

Примечание. Необходимо выполнить эту команду с другого компьютера и с использованием другого_пользователя (не vm_user).

Одинарные кавычки соответствуют ' перед echo.

Barmar 26.04.2023 17:43

Такое смешивание команд ssh и sudo будет сложным, потому что требуется так много уровней цитирования, и они не вложены чисто.

Barmar 26.04.2023 17:48

Правильно @Barmar, но это требование. Я не могу выполнить этот скрипт на той же машине, и только other_user может писать в CONFIG_FILE.

Kalit Inani 26.04.2023 17:52

Обязательно ли делать это с echo? Разве вы не можете скопировать содержимое в виде файла на удаленную машину?

Barmar 26.04.2023 17:56

Я должен добавить к существующему файлу, присутствующему на другой машине. Существующий файл не может быть полностью перезаписан.

Kalit Inani 26.04.2023 17:59

Я никогда не говорил иначе. scp filename remote:/tmp/new; sudo other_user "cat /tmp/new >> $CONFIG_FILE"

Barmar 26.04.2023 18:06

Научитесь проверять свой код на shellcheck.net. Если это не исправит, используйте обновленный код в своем вопросе. Удачи.

shellter 26.04.2023 19:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Гораздо более простое решение — выполнить все расширение локально, а затем просто записать результат в конец конвейера.

config_file=/tmp/config.txt
element_list=("element1" "element2")
for element in "${element_list[@]}"
do
    read -r -d '\n' content <<____EOM
field1 = on
field2 = '$element'
field3 = '$element-random-text'
____EOM
    echo "$content"
done |
sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -c \"cat >> '$config_file'\""

Захват документа здесь только для того, чтобы вы могли сразу же echo это, очевидно, пустая трата памяти; Я полагаю, что ваше настоящее тело петли выглядит более сложным.

Не используйте верхний регистр для своих личных переменных; см. Правильный ввод переменных в сценариях Bash и shell. Для надежности я также добавил двойные кавычки вокруг ${element_list[@]}; см. Когда заключать в кавычки переменную оболочки

Спасибо, это было полезно. Дополнительное изменение, которое потребовалось, заключалось в заключении команды sudo su - other_user -c "cat >> '$config_file'" в двойные кавычки. Итоговая команда выглядела так: sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -c \"cat >> '$config_file'\""

Kalit Inani 27.04.2023 06:38

Я удалил ненужные кавычки вокруг команды sudo su, чтобы упростить командную строку. В команде нет метасимволов оболочки, поэтому ssh с радостью позволит вам уменьшить цитирование.

tripleee 27.04.2023 06:39

Сначала я пробовал без кавычек, но это выдало эту ошибку: bash: /tmp/config.txt: Permission denied. Хотя заключение всей команды в двойные кавычки исправляет это. Может быть, это потому, что я использовал ssh -t

Kalit Inani 27.04.2023 06:44

Аааа, я вижу, команду sudo нужно заключать в кавычки отдельно, чтобы удаленная оболочка не пыталась добавить файл до получения привилегий. Я обновлю ответ - спасибо за отзыв!

tripleee 27.04.2023 06:46

Другие вопросы по теме