我正在编写一个bash脚本,它会产生许多后台进程.我想在进程终止时收到通知; 我想知道终止过程的pid.
我已经看过使用wait,这样每个衍生进程的pid都被捕获并存储在一个数组中,然后遍历数组,并在每个进程上调用wait.这里以各种方式描述了这种技术:
如果我理解正确的话,问题在于,如果您希望在单个进程终止后立即执行某些操作,则效率相对较低.例如,如果您生成进程A和B,并且B在A之前完成,则执行必须等待A和B完成.B完成后我需要立即执行操作.
trap SIGCHLD当孩子终止时,似乎是立即执行操作的方法,但问题是我找不到确定SIGCHLD信号源的pid的方法,这也是我需要的.我发现的最接近的一个例子就是这篇文章中的第三个代码示例:
http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187
为方便起见,我在这里复制粘贴:
#!/bin/bash
iNext=0
function ChildReturned() {
wait $1
echo "$1 was returned. Its exits status was: $?"
iNext=$((iNext+1))
StartChild $iNext
}
function StartChild {
./child $1 &
pid=$!
echo "Started: $1 PID= $pid"
trap 'ChildReturned $pid' SIGCHLD
}
set -bm
for (( iNext=0; iNext<=10; iNext++ ));
do
StartChild $iNext
done
wait
Run Code Online (Sandbox Code Playgroud)
我认为这个例子不起作用,因为作者犯了trap多次调用的错误,每次都在trap's参数中捕获一个不同的pid变量.每次调用陷阱时,它都会覆盖先前的调用,因此将捕获任意pid.我找不到更好的技术.
有没有办法在bash中使用陷阱获取已终止子进程的pid?
更新
我只想指出这个资源,其中包含迄今为止我所看到的解决此问题的最佳,最全面的概述:
在linux shell脚本中我有
vlc /some/file/path.mkv &
wait
Run Code Online (Sandbox Code Playgroud)
现在直到我的后台进程返回wait调用将被阻止。但在这里我希望在后台进程返回之前我想执行一个循环并在其中连续打印一些数据。因此,当我的后台进程返回/退出时,我需要打破该循环。
如何在 shell 脚本中做到这一点?
这是一个示例程序:
#!/bin/bash
for x in {1..5}
do
output[$x]=$(echo $x) &
done
wait
for x in {1..5}
do
echo ${output[$x]}
done
Run Code Online (Sandbox Code Playgroud)
我希望它运行并打印出分配给output数组每个成员的值,但它什么也不打印。删除&正确分配变量。我必须使用不同的语法来并行实现吗?
在bash脚本中需要帮助.目标是: - 并行运行多个命令 - 如果任何命令返回非零退出状态,则退出1
即
使用middle命令运行有错误:
$ ./parallel_commands "echo 1" "_echo 2" "echo 3" && echo "OK"
1
3
./parallel_commands: line 4: _echo: command not found
OK <- Incorrect
Run Code Online (Sandbox Code Playgroud)
使用所有命令运行都有错误:
$ ./parallel_commands "_echo 1" "_echo 2" "_echo 3" && echo "OK"
./parallel_commands: line 4: _echo: command not found
./parallel_commands: line 4: _echo: command not found
./parallel_commands: line 4: _echo: command not found
-> Result is fail -> Correct
Run Code Online (Sandbox Code Playgroud)
Bash脚本:
#!/bin/bash
for cmd in "$@"; do {
$cmd & pid=$! …Run Code Online (Sandbox Code Playgroud) 在 Bash 中,我想并行多次调用一个命令,同时捕获所有进程的退出代码。
我知道如何启动并等待它们,但是等待只会给我最后一个进程退出的退出代码。我还需要生命周期较短的进程的退出代码。
不幸的是我没有 bash 4.3,所以wait -n不是一个选项,gnu 并行也不是#3004811中建议的
#16032001几乎问了同样的问题,但也没有提供解决方案。
我目前能想到的唯一方法是编写一个帮助程序脚本,将退出代码存储在文件中,但这听起来不像是一个干净的解决方案。
背景
我正在研究一个bash脚本,以自动化构建位于同一目录中的六个项目的过程.每个项目都有两个要运行的脚本来构建它:
npm install
npm run build
Run Code Online (Sandbox Code Playgroud)
第一行将从npm获取所有依赖项.由于此步骤耗时最长,并且由于项目可以同时获取其依赖项,因此我使用后台作业来并行获取所有内容.(即:npm install &)
第二行将使用这些依赖项来构建项目.因为这必须在所有步骤1完成之后发生,所以我wait在中间运行命令.请参阅下面的代码段.
问题
我想在任何后台作业或npm run build之后发生的步骤中发生错误时立即退出脚本.
我正在使用set -e,但这不适用于后台作业,因此如果一个项目无法安装它的依赖项,其他一切都会继续.
这是我的脚本现在看起来如何的简化示例.
build.sh
set -e
DIR=$PWD
for dir in ./projects/**/
do
echo -e "\033[4;32mInstalling $dir\033[0m"
cd $dir
npm install & # takes a while, so do this in parallel
cd $DIR
done
wait # continue once the background jobs are completed
for dir in ./projects/**/
do
cd $dir
echo -e "\033[4;32mBuilding $dir\033[0m"
npm run build # …Run Code Online (Sandbox Code Playgroud) 我有一个 bash 脚本,可以并行执行一些耗时的命令,到目前为止它运行得很好。我正在使用等待命令,如下所示:
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
composer install -n &
wait
Run Code Online (Sandbox Code Playgroud)
现在,我希望此脚本中止所有命令,并在其中一个命令失败时给出退出代码。如何实现这一目标?
注:*/*是docker镜像名称,对于上下文来说不重要