![为什么使用“At”实用程序后不能自由使用 bash?(直到按下 ctrl+c 才能插入 stdin)](https://linux22.com/image/996901/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%BF%E7%94%A8%E2%80%9CAt%E2%80%9D%E5%AE%9E%E7%94%A8%E7%A8%8B%E5%BA%8F%E5%90%8E%E4%B8%8D%E8%83%BD%E8%87%AA%E7%94%B1%E4%BD%BF%E7%94%A8%20bash%EF%BC%9F%EF%BC%88%E7%9B%B4%E5%88%B0%E6%8C%89%E4%B8%8B%20ctrl%2Bc%20%E6%89%8D%E8%83%BD%E6%8F%92%E5%85%A5%20stdin%EF%BC%89.png)
我运行了以下代码块(at
卸载 PHPmyadmin 的超时)。它应该安排在 2 小时后运行,但我在 2 分钟的超时内运行它,只是为了测试它:
bash /dev/fd/50 50<< PMA_UNINSTALL | at 'now + 2 minutes'
apt-get purge phpmyadmin -y
PMA_UNINSTALL
该at
实用程序似乎阻止我自由使用 Bash,除非我执行CTRL+ C。At
还会提示以下警告,这是正常的,并且硬编码在实用程序的源代码中。当我执行CTRL+C时,警告消失,我又可以正常使用 Bash 了。
命令将使用 /bin/sh 执行
我不会说只要出现警告,我就无法定期使用 Bash。我知道警告只是 stdout,其他东西可能会阻止我创建 stdin。
是什么阻止我创建 stdin 管道上述代码块,at
以及如何达到可以执行用 at 管道传输的命令的状态,但之后可以自由使用 Bash 而不会中断at
工作?
答案1
我花了一些时间才发现你的真正问题——你想直接发送命令,at
而不是像我假设的那样事后提供命令。
不需要复杂的方案,只需输入
echo 'apt-get purge phpmyadmin -y' | at 'now + 2 minutes'
当您以这种方式执行操作时,at
之后不需要任何输入,并且您会立即返回到命令行。
(此处保留我原来的答案)
发出后,at
您可以列出要执行的命令。您必须告诉at
他们您已完成:
按CTRL+ D(这也称为传输结束)
答案2
TL;DR:这些命令似乎并没有实现您想要的效果。
如果您尝试在 2 分钟内at
执行,那么您的代码将不会执行您希望它执行的操作。apt-get purge phpmyadmin -y
bash
管道 ( ) 左侧的命令|
将您的 here document 作为其标准输入。该命令直到 shell 读取了您的整个 here document 后才会运行。
这种重定向指示 shell 从当前源读取输入,直到一行仅包含单词(没有尾随空格)被看到。 到该点为止读取的所有行随后被用作标准输入(或文件描述符n如果n为命令指定。
带有 here document 的命令实际上只是一个命令,在执行之前必须由 shell 完全读取。在你的代码中,shell 读取输入直到 PMA_UNINSTALL
单独出现在一行上。一旦发生这种情况,shell然后使用此处文档的内容作为命令的文件描述符 50 bash /dev/fd/50
。
该命令甚至不会启动新的实例,bash
直到此处的文档被完全读取。bash
运行时,它会运行以下命令:
apt-get purge phpmyadmin -y
由于管道的整个左侧包括此处的文档有它的标准输出管道到at
,输入at
得到的是输出,bash
这是 的输出apt-get purge phpmyadmin -y
。at
然后尝试解释该输出——不是你的apt-get
命令,而是它的输出——作为要在 中执行的命令列表/bin/sh
。
所以这几乎肯定不是你想要做的。
我不确定为什么在输入该代码后没有立即返回 shell 提示符。当我在测试机器上运行它时,我会在几秒钟内返回 shell 提示符。如果您想调试它,可以尝试apt-get purge phpmyadmin -y
在 bash 中以交互方式运行。按照您的代码编写方式,该命令完全运行前 at
返回到 shell(在at
可以安排任何事之前)。不过,进一步调试此特定代码可能没什么用。