如何在脚本中前景工作?

Jon*_*röm 12 bash shell-script background-process

我想启动一个测试,然后稍等片刻,然后使用 shell 脚本启动一个程序:

#!/bin/bash
sleep 3 &  # test
sleep 1    # wait some
sleep 4 &  # run program under test
fg 1       # <-- I want to put test back in "foreground", but yields "line 5: fg: no job control"
Run Code Online (Sandbox Code Playgroud)

我想我误解了“前景”的意思,但是还有其他方法可以做我想做的事吗?(我尝试使用jobs -xand前缀nohup,但我怀疑我的误解更深了。)

And*_*y K 22

您只需要在 shell 中启用作业控制 set -m

#!/bin/bash
set -m
sleep 3 &  # test
sleep 1    # wait some
sleep 4 &  # run program under test
jobs
fg %1
Run Code Online (Sandbox Code Playgroud)

引用自 bash 手册:

-m

监控模式。作业控制已启用。对于支持它的系统上的交互式 shell,默认情况下启用此选项(请参阅上面的 JOB CONTROL)。后台进程在单独的进程组中运行,并在完成时打印一行包含其退出状态的行。

  • 即使前面的作业已经完成,后台作业也会按顺序编号,因此每个作业都会增加计数器,无论是否完成。如果可能的话,最好不要使用作业编号 - 如果作业 1 是“testscript”而作业 3 是“myprog”,那么您可以使用作业标识符 %te 或 %myp 只要它不模棱两可,就更容易跟踪 (8认同)
  • 您不知道 %1 是 sleep 3 还是 sleep 4。如果 sleep 3 在 sleep 4 开始时已经完成,那么 sleep 4 是作业 %1 (2认同)

Kus*_*nda 22

#!/bin/bash

sleep 3 & sleep_pid=$!
sleep 1
sleep 4 &
wait "$sleep_pid"
Run Code Online (Sandbox Code Playgroud)

把它sleep 3放在前台相当于等待它完成。我假设这是你想要做的(或者至少这是你正在寻找的效果),这就是上面的脚本所做的。它通过将作业的 PID 保存在变量中sleep_pid,然后在调用wait.

您还可以使用作业 ID:

#!/bin/bash

sleep 3 &
sleep 1
sleep 4 &
wait %1
Run Code Online (Sandbox Code Playgroud)

  • @TobySpeight AFAIK 在信号方面并不等效。我试图明确我的代码的作用,即等待 `sleep 3` 调用完成。我假设这是用户想要的。在前台调用 `sleep` 的效果是等待它完成。如果用户出于任何_特定_原因想把它放在前台,他们没有提到它。 (4认同)
  • 这真的是等价的吗,包括终端输入的“SIGTSTP”和“SIGINT”?(真正的问题;我想知道) (2认同)