4

I have the following script update_pos_databases.php (simplified version)

<?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";
}
?>

When I invoke it I do the following:

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

Since I use the system command in the php script is there any issue when using the above command can cause if one of the system commands fails for some reason? I think what I am doing is fine; but before I deploy this change I want to know of any dangers of using system() inside a script that gets called with nohup. (I don't want the script to die for some random reason).

Also will the individual system command in the script above be blocking? I want to make sure they run 1 by 1 without all running at the same time.

Chris Muench
  • 17,444
  • 70
  • 209
  • 362
  • if the mysql command has an error will I miss this? Or is all of mysql being directed to standard out? It looks like I still get it in standard out – Chris Muench Apr 18 '15 at 18:38
  • ahh, sorry, I'm a bit hungover, you have it right. :) – Rooster Apr 18 '15 at 19:02
  • If you want to run them one by one - then just don't try to pass it over to somewhere. Run it without placing to background so main script will actually wait till the process is finished. And - no - once it's put to the background, there's no guarantee it will "run in order" - there's only a guarantee that "starting time" will follow your loop logic. But how and when the corresponding script will finish - is another story – Alma Do Sep 08 '15 at 15:24
  • 1
    nohup only puts the php process in the background, doesnt affect the order of the system processes, they will execute in the order determined by the loop and they will wait to finish. Also you dont need the & to put the process in background in the command line, nohup already does it. I have doubts about the < redirection inside the system anyway. – PerroVerd Sep 08 '15 at 15:45

2 Answers2

1

Just a proof of concept

<?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";
}

?>

As you will see this code executes the uptime commands one by one, if there is a problem like the jhsddf command it will display the error and continue the execution.

Results:

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

The only option to have diferent orders is to call the nohup in every system process (nohup mysql... in yor case). They will have the start order defined by the script but you will not be able to ensure the finish order because they will execute simultanously

PerroVerd
  • 945
  • 10
  • 21
  • Thank you for the answer. I do NOT want a different order; I just want to make sure nohup doesn't cause issues with php system command in terms of order. – Chris Muench Sep 08 '15 at 16:13
1

nohup will keep the process going even after terminal disconnect (eg, logout) and & will put that process in the background. Yes, each system will run to completion before iterating to the next loop: php has no idea it's being run no-hupped.

Here is a reduced example showing these behaviors:

$ 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

So, your script seems to be written to run as you expect. The only modification I'd suggest is putting the full path to your MySQL command line executable in your system statement.

Community
  • 1
  • 1
bishop
  • 37,830
  • 11
  • 104
  • 139