【问题标题】:Run command `at ` 5 seconds from now从现在开始 5 秒后运行命令 `at`
【发布时间】:2012-12-04 01:27:06
【问题描述】:

作为一个稍微复杂的脚本的一部分,我需要告诉服务器运行模拟。通常,我会通过ssh user@server 'simulation/script' 来实现这一点。但是,这样做会使 ssh 会话保持活动状态,直到完成 'simulation/script',这对我来说是不可取的。

我最近了解了at 命令,它似乎很适合我的问题。
我现在想要做的是 ssh 进入我的服务器,at 我的模拟脚本在 5 秒内运行(足够关闭 ssh 连接的时间)。因此,一旦 ssh 连接在 5 秒内关闭,服务器将开始模拟,而无需 ssh 连接保持活动状态。

我遇到的问题是at 需要的时间表达式来安排“从现在起 5 秒后”的作业

我尝试了以下时间表达式,所有这些都给我错误:

now + 5 seconds
now + 5 sec
now + 5 s
now + 5seconds
now + 5sec
now + 5 s
now+5sec
now+5seconds
now+5s

我怎样才能让我的at 在“5 秒后”运行我的命令?

【问题讨论】:

  • 与其乱搞at,或许你只想要ssh user@server bash -c '"simulation/script &"'...
  • 我在 package.json 脚本中使用它,所以我必须这样做以防止进程被阻止:( sleep 5 && delayed_command ) & immediate_command。如果您不希望输出显示在STDOUT 中,我还在delayed_command 之后添加了> /dev/null 2>&1

标签: linux bash scheduled-tasks


【解决方案1】:

没有在:

man at 说:

  • 日期规范必须遵循一天中的时间规范。你也可以像现在这样给出时间+计数时间单位, 其中时间单位可以是分钟、小时、天或周,并且 你可以告诉 at 今天通过给时间加上今天的后缀来运行工作,并通过给时间加上后缀来告诉明天运行工作 明天。

所以我认为你可以使用sleep 而不是at

man 1 sleep


如果您想在不等待的情况下运行ssh user@server 'simulation/script',只需执行以下操作:

ssh user@server 'simulation/script' &

该命令将在后台运行。

此外,正如 Rawkode 所说,nohup 将在这方面提供帮助。

所以最后:

nohup ssh user@server 'simulation/script' &

使用 nohup,您可以退出终端并让 ssh 进程处于活动状态。


EDIT:如果你想运行ssh命令并关闭连接:

ssh user@server 'simulation/script &'

【讨论】:

  • 但是如果我&ssh,套接字不会仍然保持打开状态吗?
  • 脚本完成后socket会关闭
  • 这对我来说是个问题。我需要在脚本开始之前关闭套接字
  • 使用& 将不起作用,因为我必须使用 ctrlc 手动终止 ssh 连接。这是不可自动化的。我需要自动化,终止 ssh 连接并运行脚本。这就是为什么我想到now。我想我应该硬着头皮去做now + 1 minute
  • 默认情况下,远程后台运行命令后ssh会关闭。我不明白你的问题。
【解决方案2】:

at 不使用秒,只使用分钟/小时/天

您可以做的是在您的脚本前面加上nohup,这将确保在您断开 SSH 会话时脚本不会被终止。

ssh server 'nohup yourscript.sh &'

注意:刚刚玩过上述操作,必须手动终止 SSH 连接。

另一种选择是screen

screen -d -m yourscript.sh

这将启动一个分离的screen 进程,您可以在以后随时重新附加该进程。

注意:我已经使用以下脚本和命令对此进行了测试,并且效果很好。

SSH 命令

ssh server.com 'screen -d -m ~/myscript.sh'

myscript.sh

#!/bin/sh
sleep 10
echo "hello world" > /tmp/hello
exit;

【讨论】:

  • nohup 有什么帮助?我以前从未使用过它……
  • nohup 不会在您断开连接时终止该命令。我知道您已经使用 at 1 minute,但我会更新我的答案以供其他人参考。
  • 我仍然对nohup 的实现感兴趣(可能用于未来的项目),所以感谢您的努力。我是否必须手动终止 ssh 连接,或者是否可以使用 nohup 自动终止
  • 如果您将命令放在ssh 行中,ssh 将在命令执行后退出。 ssh server 'command'
  • 有没有办法让ssh在远程命令执行结束之前终止连接,同时在远程主机中保持远程命令处于活动状态(这就是我去调度作业的原因而不是sshnohup)?
【解决方案3】:

重定向 stdin/stdout/stderr 除了后台脚本将允许 SSH 会话在执行后台命令后立即关闭:

ssh hostname "/path/to/script </dev/null >/dev/null 2>/dev/null &"

来源:https://serverfault.com/a/36436/138334

【讨论】:

  • 难道你还需要nohup 来避免SSH会话关闭时进程被杀死吗?
【解决方案4】:

请注意:在man at 中,我看到有一个-t 开关,它将接受带秒的日期时间 - 但不幸的是,秒将被截断:

$ date; date --date="now +10 seconds" +"%m%d%H%M.%S"; echo "logger AAAA" | at -t $(date --date="now +5 seconds" +"%Y%m%d%H%M.%S")
Thu Feb  5 14:45:57 CET 2015
02051446.07
warning: commands will be executed using /bin/sh
job 8 at Thu Feb  5 14:46:00 2015

...因此该作业实际上可能是在过去安排的(此外,将logger 用于系统日志,因为它看起来不像回显到终端的标准输出可以从这里工作)

【讨论】:

  • MacOS下其实是考虑秒数的
【解决方案5】:

我认为这样做更容易:

sleep n && command   

n 是秒数。

【讨论】:

    【解决方案6】:

    “at”没有亚分钟分辨率,但你可以伪造它:

    echo "sleep 5 ; COMMAND" | at now
    

    【讨论】:

    • 这也是我想出的,它经过测试可以工作 ala echo "sleep 23; date &gt; /tmp/date.txt" | at 13:30 并且就在 13:30:23 之后,/tmp/date.txt 的内容确实是“... 13:30:23..."
    • 我将其简化为 sleep 5 ; COMMAND 并且有效。它具有在当前环境(包括 X 服务器)中运行命令的结果,这在您想在几秒钟后创建屏幕截图时很有用:sleep 5 ; import -window root ~/screen_$(date "+%F_%H-%M-%S").png
    【解决方案7】:

    你可以使用 sleep 命令来做到这一点:

    bash -c 'sleep 5 ; echo "test"' &
    

    【讨论】:

      【解决方案8】:

      我今天遇到了同样的问题,但我能够使用 nohup 解决它

      nohup bash -c 'sleep 5 &amp;&amp; at now -f script-name.sh'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-21
        • 2020-09-12
        • 1970-01-01
        • 2020-10-06
        • 1970-01-01
        • 2020-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多