监视生成的子进程,以便在生成另一个子进程之前完成

时间:2017-11-19 10:01:33

标签: php bash shell unix

我需要针对以下问题提供一些指示。

我需要运行6个进程。这些是我需要从shell脚本生成的PHP文件。我能够做到,但结果不是我想要的。

执行顺序如下。

  1. 需要提交Process1,除非完成流程2,否则无法提交流程5。
  2. 过程2到过程5可以并行提交。
  3. 流程最终需要在流程2到流程5完成后提交。
  4. 我搜索了各种页面,但无法找到解决方法。我引用的页面如下所示。

    https://unix.stackexchange.com/questions/76717/bash-launch-background-process-and-check-when-it-ends

    Waiting for background processes to finish before exiting script

    无论我按照上述链接做了什么,所有过程都会同时提交。请指导我。代码如下。

    #!/bin/sh
    start=`date +%s`
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process1 
    wait
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process2
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process3
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process4
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process5
    
    wait
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=final
    
    end=`date +%s`
    runtime=$((end-start))
    echo "$runtime"
    

    请注意我是新手,对shell过程了解不多。

    将欣赏任何指示和反馈。

    由于

3 个答案:

答案 0 :(得分:1)

您可以在后台添加&来运行程序, 并且您可以使用wait等待后台进程完成:

#!/bin/sh

start=$(date +%s)

php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process1 

php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process2 &
php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process3 &
php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process4 &
php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process5 &

wait

php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=final

end=$(date +%s)
echo $((end - start))
不过,你应该避免复制粘贴编码。 将重复的值放在变量中,以便稍后在一个地方进行更改, 并为辅助函数提取通用逻辑。

#!/bin/sh

run() {
    local process_name=$1
    php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name="$process_name"
}

start=$(date +%s)

run process1 

for i in 2 3 4 5; do
    run process$i &
done

wait

run final

end=$(date +%s)
echo $((end - start))

答案 1 :(得分:0)

@janos提供的解决方案很棒,但问题在于我调用PHP代码的方式。从浏览器调用PHP脚本与Shell不同。下面给出了修改代码以接受来自浏览器和shell的值。

if ($argc <2) //positional argument count passed from shell
{//Execute this when the browser makes the call
    if ((isset($_REQUEST['user_id'])) && (!empty($_REQUEST['user_id'])))
    {
            $user_id = $_REQUEST['user_id'];
        echo 'Hi';
        }else{

            $output['error'] = "Invalid User.";
        }
    if ((isset($_REQUEST['process_name'])) && (!empty($_REQUEST['process_name'])))
    {
        $process_name = $_REQUEST['process_name'];

    }else{//Execute this when call is made from shell

        $output['error'] = "Invalid Process Name";
    }

}
else
{
    $user_id = $argv[1]; //positional argument value passed from shell
    $process_name = $argv[2]; //positional argument value passed from shell
}

答案 2 :(得分:0)

使用GNU Parallel,它看起来像这样:

#!/bin/sh
start=`date +%s`
php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=process1 
parallel php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name={} ::: process{2..5}
php /usr/share/nginx/html/cron/complete-api-fetch.php user_id=6 process_name=final

end=`date +%s`
runtime=$((end-start))
echo "$runtime"