Jay*_*itt 5 scripting bash sudo stdin
我经常编写 wiki 说明以在 Ubuntu(目前为 11.10 Oneiric)上安装各种服务器包。它们总是涉及以下内容:
sudo apt-get install -y postfix
sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
Run Code Online (Sandbox Code Playgroud)
但是当您将其剪切并粘贴到终端时,sudo、apt-get 或某些子shell 会随机吞下后续的输入行,并且只会apt-get install发生这种情况。
有没有办法让它更易于剪切和粘贴?我想我可以用
cat > script <<EOF
apt-get install -y postfix
cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
EOF
sudo sh ./script
Run Code Online (Sandbox Code Playgroud)
但有更好的方法吗?
有一个关于此的出色错误报告:Debian 错误报告 #728775 - apt-get unwarrantedly消耗输入。报告说:
当以涉及实际安装包的方式调用 apt-get 时,它会从标准输入读取任何可用数据,而不管实际需要。这打破了在交互式 shell 中在当前命令运行时键入下一个命令的通常能力:apt-get 消耗了用于 shell 的输入。strace 显示输入由顶层 apt-get 进程读取,由 fd 0 的 read(2) 读取,以响应 pselect(2)。
...
它在 apt-pkg/deb/dpkgpm.cc 中的 pkgDPkgPM::Go() 中。在相同的函数下方,有一个 pselect 循环,它确实与我在 strace 中看到的相匹配。它仅在 (master >= 0 && !d->stdin_is_dev_null) 条件下从标准输入读取
在回应中:
这是为了避免有人在下载软件包时输入他们的下一个命令,但随后该输入被用作安装过程中提示的答案。
由于您已经提供apt-get了-y选项,因此您可能不希望它提出问题或阅读回复,因此对您的解决方法是将 stdin 重定向到 /dev/null。当我执行以下操作时:
apt-get install -y gdb-doc < /dev/null
Run Code Online (Sandbox Code Playgroud)
我在执行apt-get命令期间预先输入的内容没有刷新。
避免剪切和粘贴问题以及安全地连续运行命令的一种方法是将它们放在同一行中,由&&它分隔,只有cp在成功完成时才会执行sudo apt-get install:
sudo apt-get install -y postfix && sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
Run Code Online (Sandbox Code Playgroud)
毕竟,如果第一个命令失败,您可能不想继续执行其余的命令。
至于为什么当您一次粘贴多行时命令会被吞下......安装后缀时,它会询问 debconf 对话框前端的配置问题,这可能是干扰剪切和粘贴的原因。也许不同的前端,如 readline 或非交互式会减少干扰?尽管如此,我还是会使用该&&方法,因为它更安全。
如果您使用脚本安装 postfix,听起来您可能正在尝试自动安装新系统?如果是这样,请考虑使用预置作为选项(这里有一些Ubuntu 11.10 特定文档)或者使用puppet?