【问题标题】:Why is my "at" command in terminal not functioning?为什么我在终端中的“at”命令不起作用?
【发布时间】:2015-02-04 00:50:14
【问题描述】:

例如,我正在尝试使用 echo "haha" | at 20:30 让我的命令在几分钟内执行。

但是命令永远不会执行:

$ date
Tue  3 Feb 2015 20:47:22 AST
$ echo "test" | at 20:48
job 5 at Tue Feb  3 20:48:00 2015
$ date
Tue  3 Feb 2015 20:48:05 AST

我做错了什么?

【问题讨论】:

  • 你为什么认为你做错了什么? atd 将命令作为其守护进程的子进程运行——即使test 命令确实 有任何输出(它没有),也不会输出到您的终端。
  • 还要记住——echo "test" | at 20:48 不会将echo "test" 发送到at,它会将test 发送到at;一个shell管道将左侧命令的输出连接到右侧命令的输入,echo "test"的输出为test
  • @CharlesDuffy 那么如何向 at 发送命令?
  • 嗯,正常的方法是使用引用的 heredoc,但我需要写一个完整的答案来描述它。
  • 天啊,我只想让一个命令在某个时间执行,通常是几分钟后。我是不是把事情复杂化了?

标签: macos bash command-line terminal


【解决方案1】:

你的命令:

echo "test" | at 20:48

告诉at 执行不带参数的命令test。它是一个可以运行但失败的内置 shell。试试:

test
echo $?

它为我生成1,表示失败。

你可能想到的是这样的:

echo "echo test" | at 20:48

现在您只需要知道输出的去向。 /dev/null 是一个合理的猜测。所以,试试吧:

echo "echo test > /tmp/x39.214" | at 20:48

然后,当 20:48(或您选择的新时间)来临时,查找文件 /tmp/x39.214 以包含行 test

at 命令读取其标准输入以执行一系列命令。它们在您的环境中运行,但没有连接终端(因此/dev/null 是标准输入、输出、错误——或者,如果不是,您将在电子邮件中获得输出)。因此,您的命令必须安排将其输出存储在您可以找到的地方。像/tmp/x39.214 这样的固定名称不是一个好主意,但您需要能够确定文件的去向和名称。通常,名称会包含时间。

因为at 读取标准输入,您可以使用任何您喜欢的方式重定向标准输入,使用here doc,或here 字符串,或从文件,或使用管道,仅命名四种机制。

$ echo "echo test >/tmp/x39.214" > file1.txt
$ at 20:48 < file1.txt
$ at 20:48 <<'EOF'
> echo test >/tmp/x39.214
> EOF
$ at 20:48 <<< 'echo test >/tmp/x39.214'
$ cat file1.txt | at 20:48
$

我已经省略了上面每个命令的at 的输出。

您可以使用at -l 列出作业并查看将运行的内容。

【讨论】:

  • echo "test" 在终端工作,为什么它会认为我正在尝试执行“测试”命令?
  • echo "test"test 相呼应,不是吗?这就是at 视为其标准输入的内容。它根本看不到echo
  • 我的印象是at 部分只是在某个时间安排上一个命令。它到底在做什么?如果我在终端中写echo "echo test",它会显示“回声测试”。那么为什么它会在文件中做我想做的事情呢?
  • 它调度上一个命令的标准输出。例如,您将从echo "test" | cat 得到什么?答案是test(不带引号)。这就是at 看到的输入。那里没有什么特别的魔法。您可以让程序生成一个巨大的 shell 脚本或单行命令,并将该输出提供给 at 命令。您选择了一个非常简单的单行命令。
  • @DougSmith,它不会将输出写入终端的原因是 at 命令调度命令由 at 守护进程运行,而 at daemon 根本没有连接到任何终端。 (当然,这也意味着您的系统必须配置为运行 at 守护程序——如果不是,则永远不会调用由 at 调度的命令。
【解决方案2】:

传统用法更像是:

at 20:48 <<'EOF'
echo "test" >/tmp/hello_world
EOF

在预定的时间过去后检查/tmp/hello_world


在这种情况下,您发送到at 命令的标准输入的是整个文档——&lt;&lt;'EOF' 和以下EOF 之间的所有内容。

【讨论】:

    猜你喜欢
    • 2018-02-09
    • 2021-12-18
    • 2021-06-06
    • 2015-03-14
    • 2018-09-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多