尝试复制/粘贴具有多个 EOF 的长脚本,终端中途开始运行

尝试复制/粘贴具有多个 EOF 的长脚本,终端中途开始运行

正在尝试创建一个文本块,我只需将其复制并粘贴到终端窗口中即可完成某些操作(在本例中,创建一个 systemd 脚本来对 MySQL 数据库进行维护,创建一个计时器文件来每周运行该脚本,并启用剧本)。

将其粘贴到终端时,它会显示一半的脚本(直到第一个 EOF),通过读取提示输入密码,然后复制键入的密码以及 $pass 所在位置的脚本的其余部分第一个文件。

这是块:

sudo sync && echo 'Enter MySQL password for Maintenance user' && read pass && sudo bash -s -c 'cat > "/usr/lib/systemd/system/db-m.service"' << "EOF"
[Service]
Type=oneshot
ExecStart='/usr/bin/mysqlcheck' --auto-repair --optimize --all-databases --force -u'maintenance' -p'$pass'
ExecStart='/usr/bin/sync'
EOF
sudo bash -c 'cat > "/usr/lib/systemd/system/db-m.timer"' << EOF
[Unit]
Description=Weekly database repair and maintenance

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable 'db-m.timer' && sudo systemctl start 'db-m' 'db-m.timer' && sudo systemctl status 'db-m' -l

我最近添加了“read pass”和 3 行后出现的“$pass”变量;没有这两件事,我可以毫无问题地复制并粘贴整个块。

答案1

在终端中运行的 shell 接收您粘贴到其标准输入上的脚本,并且您的脚本本身从标准输入读取。这里有一个冲突:你的脚本最终会读取它自己的一些内容。

如果您没有收到 sudo 提示,则会发生以下情况:

  1. shell 会读取整行,直到获得完整的命令。第一行开始一个here文档,因此shell不断读取here文档。
  2. 当 shell 到达第一EOF行时,它有一个完整的命令,因此它会执行它。
  3. sudo sync并运行“echo '...”。
  4. read pass运行。它读取一行输入,即sudo bash -c ….这一套pass
  5. sudo sync运行。
  6. shell 已完成执行其读取的命令,因此它读取下一行输入,即[Unit].

不要将复杂的多行 shell 代码粘贴到终端中。相反,如果您确实需要将剪贴板内容作为 shell 脚本运行,请使用谢尔或者剪辑在 X11 下,或pbpaste在 OSX 上。

eval "`xsel`"
eval "`xclip`"
eval "`pbpaste`"

但实际上,你应该做的是将其放入脚本中,#!/bin/sh在顶部。

相关内容