bash中程序的链式启动

bash中程序的链式启动,bash,shell,Bash,Shell,我想启动一个链中的程序,比如启动bash脚本startScript.sh,然后在startScript.sh链中加载某些程序 startScript.sh ./program1 & #PID=(echo $!) PID=$! echo "Wait for 10 seconds here" if ps -p $PID > /dev/null; then echo "continue"; ./program2; else echo "PI

我想启动一个链中的程序,比如启动bash脚本startScript.sh,然后在startScript.sh链中加载某些程序

startScript.sh
    ./program1 &
     #PID=(echo $!)
     PID=$!
     echo "Wait for 10 seconds here"
     if ps -p $PID > /dev/null; then echo "continue"; ./program2; else echo "PID is not running"; exit; fi
     echo "Wait for 10 seconds here"
     #if program1 is running and program2 is running, then ./program3, else exit.
我试图用$!,找到program1的运行pid!,但问题是program1本身就是一个shell脚本,它们调用了我不感兴趣的更多shell脚本。因此美元!从不给我/program1的pid,而是一些无关的东西。如何获取程序1的PID


另外,如何获取program1和program2的PID以查看它们是否正在运行,然后启动program3。

特殊参数
$在shell中(来自
manbash
):

扩展到最近放入后台的作业的进程ID,无论是作为异步命令执行还是使用bg内置(请参见下面的作业控制)

需要注意的是,作业控制是shell本地的(在您的例子中是执行
startScript.sh
bash
解释器的本地)

这意味着下面的
pid

#!/bin/bash
./program.sh
pid=$!
将始终包含
program.sh
脚本的PID(即执行它的进程,用hashbang定义,在您的情况下可能是另一个
bash
进程),而不考虑该子进程生成的后台进程(请记住,
$!
是脚本本地的;子脚本中的
$!
将是未定义的,直到生成后台进程为止)


一开始可能会偏离你的方向的是:

PID=(echo $!)
这没有正确设置PID。
PID
被设置为包含两个单词(元素)的数组:
echo
。您想要这样:

pid=$!
(可能对非全局变量
pid
)使用小写名称)


一个简单的演示:

$ cat script1.sh
#!/bin/bash
./script2.sh &
echo "in script1: $!"

$ cat script2.sh 
#!/bin/bash
echo "in script2: $!"
sleep 5 &
echo "in script2 after sleep: $!"

$ ./script1.sh
in script1: 19537
in script2: 
in script2 after sleep: 19541

注意
$!
script2.sh
中最初未定义的
$!
中是如何全局返回最后一个PID的,它将被设置为
script2.sh
的PID尝试
PID=$!
。现在您正在将
PID
设置为包含
echo
和PID>的数组(在这种情况下,这没有任何意义)。使用echo更正了错误。但问题仍然存在。program1在内部调用进一步的后台进程。因此,我猜,$!将返回进一步后台进程的pid,而不是program1的pid。program1启动更多进程并不重要,它本身就是一个进程,因此它的
pid
将在sing
$!
$!
返回当前shell/进程中最近放入后台的程序的PID。您的
程序1
是一个不同的进程。
$!
脚本中的
仅与自身放入bg的程序相关(当前正在执行
bash
进程)。您可能想查看
pgrep
谢谢您的详细解释。您还可以告诉我,如果父程序生成了一个进一步的后台无限循环子进程,是否可以找到子进程的pid?我假设,父进程在子进程死之前或除非子进程死之后才能死。因此,如果子进程p进程是无限的,那么父进程(program1.sh)甚至startScript.sh将永远不会消亡,对吗?如果子进程在后台运行,父进程可能会退出。要阻止它,请使用
wait
。您可以使用
wait PID
等待特定的PID,或者如果没有给定PID(
wait
),它将等待所有活动子进程完成。要枚举所有子进程,您必须存储它们,或稍后使用
ps
(类似于:
ps hopid--ppid“$ppid”
)。很好的解释!因此,./program1&wait$!;将强制进入进程表,即使在。/program1!的末尾有出口0。当然,假设program1有一个无限循环后台子进程。我不确定我是否理解最后一个问题,但
/program1&wait$!
相当于
/program1
/program1
仍然可以生成背景子项并在不
等待
的情况下退出。在这种情况下,父项中的
等待
将不会等待子项。