我正在尝试使用 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}
文件正在创建,但文件内未写入任何内容。
我做错了什么?我怎样才能让它发挥作用。
您不能将标准输入两次重定向到同一个命令。它要么从标准输入读取密码,要么从标准输入读取此处文档。它不能两者兼得。
您可以使用子shell来分隔两者:
sudo -S <<<"$password" bash -c 'tee /etc/systemd/system/$1 <<EOF
.... your here document
EOF
' -s "SERVICE_NAME"
如果您需要在此处的文档中使用单引号,常见的解决方案是使用我喜欢的“跷跷板引用”。紧邻包含文字单引号的双引号字符串的单引号字符串由 shell 连接成其中包含单引号的单个字符串。
sudo -S <<<"$password" bash -c 'tee /etc/systemd/system/$1 <<EOF
[Service]
ExecStart=echo "You don'"'"t say"
EOF
' -s "SERVICE_NAME"
也许还请注意这如何避免无用地使用
cat
。 sudo
可以完美地从此处文档读取标准输入(甚至不知道它来自文档;shell 会处理所有这些)。