在 shell 脚本中,我如何 (1) 在后台启动命令 (2) 等待 x 秒 (3) 在该命令运行时运行第二个命令?

Jul*_*lie 13 bash shell-script background-process

这是我需要发生的事情:

  1. 在后台启动进程A
  2. 等待 x 秒
  3. 在前台启动进程B

我怎样才能让等待发生?

我看到“睡眠”似乎停止了一切,我实际上不想“等待”进程 A 完全完成。我看过一些基于时间的循环,但我想知道是否有更干净的东西。

dr_*_*dr_ 29

除非我误解了您的问题,否则可以通过以下简短脚本轻松实现:

#!/bin/bash

process_a &
sleep x
process_b
Run Code Online (Sandbox Code Playgroud)

wait如果您希望脚本process_a在退出之前等待完成,请在最后添加一个额外的内容)。

您甚至可以单行执行此操作,而无需脚本(如@BaardKopperud 所建议的那样):

process_a & sleep x ; process_b
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您不需要为此使用 `bash`,任何 shell 都可以包含您系统的 `sh`,因此您无需为脚本添加对 bash 的依赖。 (6认同)
  • 或者简单地说: process_a & sleep x ; 进程_b (4认同)

iga*_*gal 9

您可以使用后台控制运算符 (&)在后台运行一个进程,并使用sleep命令在运行第二个进程之前等待,即:

#!/usr/bin/env bash
# script.sh

command1 &
sleep x
command2
Run Code Online (Sandbox Code Playgroud)

下面是打印出一些带时间戳的消息的两个命令的示例:

#!/usr/bin/env bash

# Execute a process in the background
echo "$(date) - Running first process in the background..."
for i in {1..1000}; do
    echo "$(date) - I am running in the background";
    sleep 1;
done &> background-process-output.txt &

# Wait for 5 seconds
echo "$(date) - Sleeping..."
sleep 5 

# Execute a second process in the foreground
echo "$(date) - Running second process in the foreground..."
for i in {1..1000}; do
    echo "$(date) - I am running in the foreground";
    sleep 1;
done
Run Code Online (Sandbox Code Playgroud)

运行它以验证它是否表现出所需的行为:

user@host:~$ bash script.sh

Fri Dec  1 13:41:10 CST 2017 - Running first process in the background...
Fri Dec  1 13:41:10 CST 2017 - Sleeping...
Fri Dec  1 13:41:15 CST 2017 - Running second process in the foreground...
Fri Dec  1 13:41:15 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:16 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:17 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:18 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:19 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:20 CST 2017 - I am running in the foreground
...
...
...
Run Code Online (Sandbox Code Playgroud)

  • 问题要求“在*前台*中启动进程B”。 (2认同)

Tre*_*ith 5

我喜欢@dr01 的回答,但他不检查退出代码,所以你不知道你是否成功。

这是检查退出代码的解决方案。

#!/bin/bash

# run processes
process_a &
PID1=$!
sleep x
process_b &
PID2=$!
exitcode=0

# check the exitcode for process A
wait $PID1    
if (($? != 0)); then
    echo "ERROR: process_a exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi

# check the exitcode for process B
wait $PID2
if (($? != 0)); then
    echo "ERROR: process_b exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi
exit ${exitcode}
Run Code Online (Sandbox Code Playgroud)

通常我将 PID 存储在一个 bash 数组中,然后 pid 检查是一个 for 循环。

  • 您可能希望在脚本的退出状态中反映这些退出代码,例如 `A & sleep x; 乙; ret=$?; 等待“$!” || 退出“$ret”` (2认同)