Как использовать опцию -S с sudo tee в скрипте bash (используйте встроенный пароль с sudo tee)

Я пытаюсь создать файл с помощью сценария bash. Вот функция, которую я использую.

function create_service_file() {

    # create service file
    echo "Creating service file /etc/systemd/system/${SERVICE_NAME}"
    cat <<- EOF | sudo tee /etc/systemd/system/${SERVICE_NAME}
        [Unit]
        Description=$DESCRIPTION
        After=syslog.target network.target

        [Service]
        User=$USER

        WorkingDirectory=${WORKING_DIRECTORY}

        ExecStart=${JAVA_HOME}/bin/java -jar ${JAR_FILE}
        ExecStop=/bin/kill -15 $MAINPID
        SuccessExitStatus=143

        Restart=always
        RestartSec=30s

        [Install]
        WantedBy=multi-user.target

        EOF
    echo "/etc/systemd/system/${SERVICE_NAME} file has been written successfully"
}

Когда я запускаю скрипт. Он запрашивает пароль в строке cat <<- EOF | sudo tee /etc/systemd/system/${SERVICE_NAME}

После ввода пароля записывает файл.

Если я проверю каталог, там есть файл

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

local is_service_failed=$(sudo -S <<< "${PASSWORD}" systemctl is-active $service)

или

sudo -S <<< "${PASSWORD}" systemctl start $service

Эти команды работают нормально. Но теперь, когда я пытаюсь использовать то же самое, это не работает. cat <<- EOF | sudo -S <<< ${PASSWORD} tee /etc/systemd/system/${SERVICE_NAME}

Файл создается, но в него ничего не записывается.

Что я делаю не так? Как я могу заставить это работать.

Низкоконтрастные снимки экрана скорее раздражают, чем информативны. Пожалуйста не публикуйте изображения кода, сообщения об ошибках или другие текстовые данные.

tripleee 29.04.2024 10:59

Не храните пароли. Вместо этого добавьте своего пользователя как NOPASSWD в sudoers. User=$USER Рассмотрите возможность использования пользовательских служебных файлов systemctl вместо системных.

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

Ответы 1

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

Вы не можете дважды перенаправить стандартный ввод на одну и ту же команду. Либо он считывает пароль со стандартного ввода, либо читает документ here со стандартного ввода. Он не может делать и то, и другое.

Вы можете использовать подоболочку, чтобы разделить их:

sudo -S <<<"$password" bash -c 'tee /etc/systemd/system/$1 <<EOF
   .... your here document
EOF
' -s "SERVICE_NAME"

Если вам нужны буквальные одинарные кавычки внутри документа, обычное решение — использовать то, что я называю «кавычным цитированием». Строка в одинарных кавычках, непосредственно примыкающая к строке в двойных кавычках, содержащей литеральную одинарную кавычку, объединяется оболочкой в ​​одну строку с одинарной кавычкой в ​​ней.

sudo -S <<<"$password" bash -c 'tee /etc/systemd/system/$1 <<EOF
   [Service]
   ExecStart=echo "You don'"'"'t say"
EOF
' -s "SERVICE_NAME"

Возможно, вам понадобится двойной взгляд на это. Это строка в одинарных кавычках bash -c '... echo "You don', примыкающая к строке в двойных кавычках "'", примыкающая к строке в одинарных кавычках 't say"...'.

Возможно, обратите внимание, как это позволяет избежать бесполезного использования кота. sudo может прекрасно читать стандартный ввод из документа здесь (и даже не знает, что он исходит из него; обо всем этом позаботится оболочка).

В любом случае, как отмечалось в комментариях, вы действительно хотите избежать встраивания своего пароля в скрипт. Настройте sudo с помощью NOPASSWD или запустите сценарий как root в первую очередь (или не требуйте привилегий root, если можете).

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