从现在开始的某个时间做一些事情(也许还可以在控制台中显示结果)

Arc*_*ing 12 sleep console stdout at delay

我使用 Ubuntu 服务器 16.04,并且我希望at在当前会话中使用该实用程序在 1 分钟后执行某些操作(例如echo),而不提供特定日期和时间 - 仅比当前时间提前 1 分钟。

这失败了:

echo 'hi' | at 1m
Run Code Online (Sandbox Code Playgroud)

我选择的原因atsleep,因为睡眠障碍当前会话是延迟命令为此更适合在另一个会话,而不是大部分时间的一个,我们的工作。AFAIR,at不会以这种方式行事,也不会妨碍我的会议。

更新_1

根据 Pied Piper 的回答,我尝试过:

(sleep 1m; echo 'hi')  &
Run Code Online (Sandbox Code Playgroud)

我对这种方法有一个问题:“hi”流打印在我的主提示中,并且还在_包含它的主提示下添加了一个空的辅助提示 ( ),请参阅:

USER@:~# (sleep 1m; echo 'hi')  &
[1] 22731
USER@:~# hi
^C
[1]+  Done
Run Code Online (Sandbox Code Playgroud)

更新_2

通过 Peter Corde 的回答,我尝试过:

(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
Run Code Online (Sandbox Code Playgroud)

这在 Bash 4.4 中可以正常工作,但在某些旧版本中似乎无法正常工作(请参阅答案中的评论)。我个人在自己的环境中使用 Bash 4.3。

Mar*_*elo 13

正确的用法是at <timespec><timespec>时间规范在哪里。您还可以使用该-f选项指定包含要执行的命令的文件。如果-f并且没有使用重定向,at 将从标准输入(标准输入)读取要执行的命令。

在您的示例中,在您按下 Enter 键(现在)后一分钟执行“some command”(我在下面的示例中选择了“some command”为“echo hi”),打算<timespec>使用的是now + 1 minute. 因此,为了通过单行解决方案获得您想要的结果,请使用以下命令:

echo 'echo hi' | at now + 1 minute

这应该(并且会)echo hi在一分钟后运行命令。这里的问题是该echo hi命令将由虚拟 tty 中的 at 命令执行,并且输出将发送到用户的邮箱(如果配置正确 - 这需要对如何配置邮箱进行更广泛的解释)一台 unix 机器,不属于这个问题的范围)。最重要的是,您将无法echo hi在发出命令的同一终端中直接看到结果。最简单的替代方法是将其重定向到“某个文件”,例如:

echo 'echo hi > /tmp/at.out' | at now + 1 minute

在上面的例子中,"some file" 是/tmp/at.out,预期的结果是at.out/tmp 下的文件在一分钟后创建并包含文本 'hi'。

除了now + 1 minute上面的例子之外,还可以使用许多其他时间规范,甚至是一些复杂的时间规范。at 命令足够智能,可以解释非常易读的命令,如下例所示:

now + 1 day, 13:25, mid?night, noon, ...

有关可能的时间规格的更多信息,请参阅 at 的手册页,因为可能的变化非常广泛,可能包括日期、相对或绝对时间等。

  • `at` 默认通过邮件发送输出,但这需要正确配置才能工作。 (2认同)

Pie*_*per 7

sleep在子shell中运行:

(sleep 60; echo -e '\nhi')  &
Run Code Online (Sandbox Code Playgroud)

注意:在 Linux 上,您可以以秒为单位或使用后缀 s/m/h/d(表示秒、分、小时、天)给出 sleep 的参数。在 BSD 上,参数必须以秒为单位

  • 阅读文档总是一个好主意:) (2认同)

Pet*_*des 6

“hi”流打印在我的提示中(在 中stdin)而不是在我的stdout

不,它不是“印在你的stdin”中。

如果您按下回车键,它就不会尝试hi作为命令运行。只是当光标在您的提示之后时echo打印了背景hi


也许您想打印一个前导换行符,例如(sleep 1m && echo -e '\nhi' &). (根据echo您的 shell 中的需要进行调整。或printf用于便携性。)

我把&里面的子外壳“否认”了后台工作,所以你也避免了[1]+ Done. 随着&&命令之间,&适用于整个复合命令链,因此它返回到shell提示符马上,而不是等待sleep退出就像你用得到(sleep 1; echo ... &)

这是发生的事情(延迟 1 秒):

peter@volta:~$ (sleep 1 && echo -e '\nhi' &)
peter@volta:~$ 
hi
       # cursor is at the start of this empty line.
Run Code Online (Sandbox Code Playgroud)

Bash 不知道echo打印了什么东西,所以它不知道它需要重新打印它的提示或清理屏幕。您可以使用control-L.

您可以编写一个 shell 函数,让 bash 在echo完成后重新打印其提示。只是这样做echo "$PS1"不会重现任何已经输入的字符。 kill -WINCH $$在我的系统上,bash 在不清除屏幕的情况下重新打印其提示行,hi在提示之前单独保留一行。SIGWINCH 在 WINdow 大小改变时自动发送,而 bash 对它的响应恰好符合我们的要求。

它可能适用于其他 shell,但我并不试图使这个 100% 可移植/POSIX。(不幸的是,这仅适用于 bash4.4,不适用于 bash4.3,或者取决于我不知道的某些设置

  # bash4.4
peter@volta:~$ (sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
peter@volta:~$ ljlksjksajflasdf dfas      # typed in 2 seconds
hi
peter@volta:~$ ljlksjksajflasdf dfas      # reprinted by Bash because of `kill -WINCH`
Run Code Online (Sandbox Code Playgroud)

您可以轻松地将其包装在一个带有 sleep arg 和消息的 shell 函数中。

bash 4.3 不会在 SIGWINCH 之后重新打印其提示,所以这在那里不起作用。我shopt -s checkwinsize在两个系统上都启用了,但它只适用于 Bash 4.4 系统(Arch Linux)。

如果它不起作用,你可以尝试(sleep 2 && echo -e '\nhi' && echo "$PS1" &),如果命令行为空,它“有效”。(它也忽略了PROMPT_COMMAND设置的可能性。)


当计时器触发时,没有真正干净的方法可以让终端输出与您以后可能在终端上做的任何事情混合。如果您正在滚动 中的某些内容less,则很容易错过它。

如果您正在寻找具有交互式结果的内容,我建议您播放音频文件。例如使用命令行播放器mpv(MPlayer2 的好分支)。或者选择一个视频文件,以便打开一个新窗口。

(sleep 1 && mpv /f/share/music/.../foo.ogg </dev/null &>/dev/null &)
Run Code Online (Sandbox Code Playgroud)

您可能希望echo打开一个新的 xterm / konsole / gnome-terminal。使用在命令退出后保持终端打开的选项。