php脚本使用系统命令并在后台运行 - 它仍会按顺序运行吗?

时间:2015-04-18 18:27:59

标签: php

我有以下脚本update_pos_databases.php(简化版)

<?php
ini_set('display_errors', 1);
set_time_limit(0);
$db_host = 'localhost';
$db_user = 'root';
$db_password = 'PASSWORD';

$databases = array('example');

$db_host = escapeshellarg($db_host);
$db_user = escapeshellarg($db_user);
$db_password = escapeshellarg($db_password);

foreach($databases as $database)
{
    echo "Running queries on $database\n***********************************\n";
    system("mysql --host=$db_host --user=$db_user --password=$db_password -v -v -v $database < ../update.sql"); 
    echo "\n\n";
}
?>

当我调用它时,我会执行以下操作:

nohup php update_pos_databases.php > results.txt 2>&1 </dev/null &

由于我在php脚本中使用system命令是否有任何问题,如果使用上述命令导致其中一个系统命令由于某种原因失败?我觉得我在做的很好;但在我部署此更改之前,我想知道在使用nohup调用的脚本中使用system()的任何危险。 (我不希望脚本因某些随机原因而死亡。)

上面脚本中的单个系统命令也会被阻塞吗?我想确保它们在没有同时运行的情况下逐一运行。

2 个答案:

答案 0 :(得分:1)

只是一个概念证明

<?php

$commands = array('uptime', 'uptime', 'jhsddf', 'uptime');
foreach ($commands as $exe) {
  echo "Begin $exe\n";
  system("$exe");
  sleep(rand(1,5));
  echo "End $exe\n";
}

?>

正如您将看到此代码逐个执行uptime命令,如果出现类似jhsddf命令的问题,它将显示错误并继续执行。

结果:

Begin uptime
 17:59:43 up 127 days,  7:41,  1 user,  load average: 0.24, 0.20, 0.18
End uptime
Begin uptime
 17:59:44 up 127 days,  7:41,  1 user,  load average: 0.24, 0.20, 0.18
End uptime
Begin jhsddf
sh: jhsddf: not found
End jhsddf
Begin uptime
 17:59:53 up 127 days,  7:41,  1 user,  load average: 0.20, 0.19, 0.18
End uptime

拥有不同命令的唯一选择是在每个系统进程中调用nohup(nohup mysql ...在你的情况下)。它们将具有脚本定义的开始顺序,但您将无法确保完成顺序,因为它们将同时执行

答案 1 :(得分:1)

即使终端断开连接(例如,退出),

nohup也会keep the process going,而&会将该进程置于后台。是的,每个system将在迭代到下一个循环之前运行完成:php不知道它是否正在运行。

以下是显示这些行为的简化示例:

$ cat demo.php
<?php foreach (range(1,10) as $i) system("/bin/date && /bin/sleep $i");

# run it without nohup, then simulate a logout
$ php demo.php > results.txt 2>&1 </dev/null &
$ kill -HUP $!
$ cat results.txt
Tue Sep  8 12:27:20 EDT 2015
Tue Sep  8 12:27:21 EDT 2015
[1]+  Hangup                  php demo.php > results.txt 2>&1 < /dev/null    

$ # do it again, this time with nohup
$ nohup php demo.php > results.txt 2>&1 </dev/null &
$ kill -HUP $!  # no effect
$ cat results.txt
Tue Sep  8 12:08:56 EDT 2015
Tue Sep  8 12:28:28 EDT 2015
Tue Sep  8 12:28:29 EDT 2015
Tue Sep  8 12:28:31 EDT 2015
Tue Sep  8 12:28:34 EDT 2015
Tue Sep  8 12:28:38 EDT 2015

因此,您的脚本似乎是按照您的预期编写的。我建议的唯一修改就是在系统语句中放置MySQL命令行可执行文件的完整路径。