Я пытаюсь создать файл с помощью сценария 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}
Файл создается, но в него ничего не записывается.
Что я делаю не так? Как я могу заставить это работать.
Не храните пароли. Вместо этого добавьте своего пользователя как NOPASSWD в sudoers. User=$USER
Рассмотрите возможность использования пользовательских служебных файлов systemctl вместо системных.
Вы не можете дважды перенаправить стандартный ввод на одну и ту же команду. Либо он считывает пароль со стандартного ввода, либо читает документ 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
, если можете).
Низкоконтрастные снимки экрана скорее раздражают, чем информативны. Пожалуйста не публикуйте изображения кода, сообщения об ошибках или другие текстовые данные.