我经常写一些wiki说明在Ubuntu上安装各种服务器软件包(11.10 Oneiric)。 他们总是涉及的东西如:
sudo apt-get install -y postfix sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
但是当你剪切并粘贴到terminal时,sudo,apt-get或者某个子shell会随机吞下随后的input行,只有apt-get install
发生。
有没有办法让这个更贴切友好? 我想我可以用每个部分来包装
cat > script <<EOF apt-get install -y postfix cp ~/siteconfig/etc/postfix/main.cf /etc/postfix EOF sudo sh ./script
但有没有更好的办法?
避免剪切和粘贴问题,以及连续安全地运行命令的一种方法是把它们放在由&&
分隔的同一行上,只有在成功完成sudo apt-get install
时才执行cp
:
sudo apt-get install -y postfix && sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
毕竟,如果第一个命令失败了,你可能不想继续执行其余的命令。
至于为什么一次粘贴多行命令会吞噬命令……当postfix被安装时,它会通过debconf对话框的前端询问configuration问题,这可能是干扰剪切和粘贴的问题。 也许像readline或noninteractive不同的前端会干扰更less? 尽pipe如此,我仍然会使用&&
方法,因为它更安全。
如果你正在用你的脚本安装postfix,那听起来你可能试图自动安装新的系统? 如果是这样的话,可以考虑使用preseeding作为一个选项(这里是一些Ubuntu 11.10特定的文档 ),或者可能使用puppet ?
有一个关于这个问题的杰出的错误报告: Debian Bug报告#728775 – apt-get不合理地消耗input 。 报告说:
当以涉及实际安装包的方式调用apt-get时,它会从标准input读取任何可用数据,而不pipe实际需要如何。 这打破了在交互式shell中通常的能力,在当前运行的命令运行时键入下一个命令:apt-get消耗用于shell的input。 strace显示input由顶层apt-get进程读取,通过从fd 0读取(2)来响应pselect(2)。
…
它在apt-pkg / deb / dpkgpm.cc中的pkgDPkgPM :: Go()中。 再往下看同样的函数,有一个pselect循环,它与我看到的strace相匹配。 它只从stdin中读取(master> = 0 &&!d-> stdin_is_dev_null)
并在回应:
这是为了避免有人在下载包时input他们的下一个命令,但是这个input被用来作为安装过程中提示的答案。
一个解决方法,因为你已经提供apt-get
-y
选项,所以可能不希望它提出问题或读取响应,是将stdinredirect到/ dev / null。 当我做到以下几点:
apt-get install -y gdb-doc < /dev/null
在执行apt-get
命令期间,我的typeahead不会被刷新。
我不确定为什么这会发生在您的贴上。 这不会发生在我身上。
也许解决scheme是社会性的,而不是技术性的。
把你的命令自己写在一行上,用文档分隔它们:
首先,我们安装postfix:
sudo apt-get install -y postfix
然后,我们取它的configuration:
sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
如果人们被迫逐行剪贴,“后续行”的问题就会消失。 而更多的文档是不是一件坏事。 🙂
对于apt-get,我发现yes
比-y
更好:
yes | apt-get install postfix
如果您的问题与apt-get install
命令相关,则可以尝试以下操作:
sudo apt-get install -y -q=2 postfix sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix
sudo apt-get install -y postfix 2>&1 |tee sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix 2>&1 |tee