【问题标题】:Start script after another one (already running) finishes在另一个(已经运行)完成后启动脚本
【发布时间】:2011-11-21 02:17:45
【问题描述】:

所以我有一个进程正在运行,它需要几个小时才能完成。我想在该进程完成后立即自动启动另一个进程。请注意,我不能在第一个脚本中添加对第二个脚本的调用,也不能创建另一个依次运行两者的脚本。有没有办法在 Linux 中做到这一点?

编辑:一种选择是使用 pgrep 每x 分钟轮询一次,并检查进程是否完成。如果是这样,请启动另一个。但是,我不喜欢这种解决方案。

PS:两者都是 bash 脚本,如果有帮助的话。

【问题讨论】:

  • 这可能以前有人问过,但我找不到。

标签: linux bash process


【解决方案1】:

也许你可以先按ctrl+z然后回车

fg; echo "first job finished"

【讨论】:

  • 一种务实(并且可能被广泛使用)的方法。
  • 我喜欢这种方法,因为它很简单。你能解释一下分号是如何与 fg 一起工作的吗?这与最初运行“myjob && mysecondjob”相同吗?
  • @ScheissSchiesser ; 分隔命令,无论它们是什么。所以在这种情况下,fg 将暂停的作业带到前台,并完成它;然后运行第二个命令。就像您提到的那样,您也可以执行fg && mysecondjob,仅当第一个(恢复的)作业返回 0 退出代码(即成功完成)时才会启动第二个作业。
  • 比每秒轮询一次以查看作业是否完成要好得多。并且无需为 pid 钓鱼而工作!
  • 这真是太棒了!
【解决方案2】:

我有同样的需求,通过以下方式解决了:

while [[ "$exp" != 0 ]]; do
exp=$(ps -ef |grep -i "SCRIPT_1" |grep -v grep |wc -l)
sleep 5;
done

调用 SCRIPT_2

【讨论】:

    【解决方案3】:

    最简单的方法:

    ./script1.sh && ./script2.sh
    

    && 表示等待 script1 成功完成后再继续执行 script2。

    【讨论】:

    • 这没有回答问题,即script1.sh 已经在运行,并且 OP 不想重新启动该进程。
    【解决方案4】:

    我遇到了类似的问题,用这种方法解决了:

    nohup bash script1.sh &

    等待

    nohup bash script2.sh &

    【讨论】:

      【解决方案5】:

      您的程序经常运行多个恶魔。在这种情况下,您的 pid 将是一个数组。只需使用:

      PID=($(pidof -x process_name)) #这会将给定进程的所有PID保存在$pid数组中

      现在,只需将 thiton 的代码修改为:

      while ps -p ${PID[*]}; do sleep 1; done ; script2

      【讨论】:

        【解决方案6】:

        民意调查可能是要走的路,但不一定是可怕的。

        pid=$(ps -opid= -C your_script_name)
        while [ -d /proc/$pid ] ; do
            sleep 1
        done && ./your_other_script
        

        【讨论】:

        • @skd: wait 如果可以使用它会更好,但 IIRC 它仅适用于子进程,而不适用于任意 PID(这太糟糕了)。
        • 我不同意。轮询几乎是永远要走的路。有了轮询,总会有关于等待循环延迟的讨论:一秒?十分之一秒?对于某些用例,您的选择可能没问题,但对于其他用例来说不是最佳选择。然而,UNIX/bash 提供了实现它的方法正确waitwait 暂停您的工作,直到另一个进程结束,然后您的工作将立即恢复。没有任意延迟。苏比托。无需循环。 除非如果您要等待的作业不是在同一个 shell 中启动的。
        • 我接受了这个答案,因为这就是我最终要做的。但是,我同意等待可能总是要走的路。这似乎仍然是一个流行的问题,所以如果有人来这里寻找答案,只需使用 @hagello 和更多建议的等待。
        • 如果进程已经停止或从未运行,这将不起作用。如果我在同名/script_name 上有多个进程,这似乎不起作用。
        • @SharkIng:如果进程可能已经终止,您可以将&& 替换为;;如果它还没有运行,除非你能检查一些副作用,否则真的没有办法确定。如果您可能有多个正在运行的脚本实例,您必须做出一些决定,即您是否正在等待所有完成、等待任何完成等。这将使脚本复杂化。
        【解决方案7】:

        您可以使用 bash 内置命令 wait wait 已经运行的进程。 man bash.

        wait [n ...] 等待每个指定的进程并返回它的 终止状态。每个 n 可以是一个进程 ID 或一个作业规范; 如果给出了作业规范,则该作业管道中的所有进程都是 等待。如果未给出 n,则所有当前活动的子进程 等待,返回状态为零。如果 n 指定一个 不存在的进程或作业,返回状态为 127。否则, return status 是等待的最后一个进程或作业的退出状态 为。

        【讨论】:

        • 这可能就是我要找的东西
        • 我认为这是最优雅的感谢。使用作业获取作业编号,然后(假设作业 2)>wait %2 && php run.php
        • 我只想指出wait 只适用于同一个shell 的子进程。
        • 仅在您运行的 pid 所在的同一 shell 中可用:stackoverflow.com/q/1058047/1695680
        • 如果是不同的 shell,你可以像这里一样使用 strace:askubuntu.com/a/1071915
        【解决方案8】:

        给定第一个进程的PID,循环

        while ps -p $PID; do sleep 1; done ; script2
        

        应该可以解决问题。这比 pgrep 和进程名称更稳定。

        【讨论】:

        • 我会修改它以不淹没终端:echo Waiting...; while ps -p $PID > /dev/null; do sleep 1; done; script2
        猜你喜欢
        • 1970-01-01
        • 2020-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-16
        • 1970-01-01
        • 2014-09-28
        相关资源
        最近更新 更多