I am having difficulty processing bash shell in php.
My problem is as below.
I have 3 tasks corresponding to 3 files bash shell (task1.sh, task2.sh, task3.sh). When task1.sh finishes processing, task2.sh will automatically execute, when task2.sh finishes processing, task3.sh will automatically execute.
Initially, I wrote a file called task.sh and embedded task1.sh, task2.sh, task3.sh into it. But I want to embed these 3 tasks into a php file.
For example: I create task.php and do the following:
If task1.sh fails, it will display popout (alert) error message.
If task1.sh processing is complete then task2.sh will continue to be automatically done.
The processing of task2.sh and task3.sh is similar to the above.
All 3 tasks I want to run backgroud. The problem is that when I run the background bash shell, I will not be able to check the failed error statement (the result always returns to 0).
I have learned a lot and consulted many documents but it did not help me.
I hope you can support me.
Sorry, my english very poor.
You may use the $retval argument of exec().
<?php
exec('task1.sh', $output, $retval);
if ($retval !== 0) {
// task 1 failed
exit('Error running task1: ' . implode("<br/>\n", $output));
}
exec('task2.sh', $output, $retval);
if ($retval !== 0) {
// task 2 failed
exit('Error running task1: ' . implode("<br/>\n", $output));
}
exec('task3.sh', $output, $retval);
if ($retval !== 0) {
// task 3 failed
exit('Error running task1: ' . implode("<br/>\n", $output));
}
You can simply use the function:
exec ( string $command [, array &$output [, int &$return_var ]] ) : string
With:
output :
If the output argument is present, then the specified array will be filled with every line of output from the command. Trailing whitespace, such as \n, is not included in this array. Note that if the array already contains some elements, exec() will append to the end of the array. If you do not want the function to append elements, call unset() on the array before passing it to exec().
return_var :
If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.
Thus you could use $output and $result_var to check the execution errors of your shells.
Regards
Related
$command1 = "interfacename -S ipaddress -N nms -P company ";
$command2 = "list search clientclass hardwareaddress Mac address ";
if ( exec( $command1 . "&&" . $command2 ) ) {
echo "successfuly executed";
} else {
echo "Not successfuly executed";
}
If command 1 (cmd query) successfully executed, I want command 2 (which also contains some cmd queries) to be executed next. In the above script, only command 1 is executed. It doesn’t show any result for command 2.
I have wasted two days on this without finding any solution.
You can use either a ; or a && to separate the comands. The ; runs both commands unconditionally. If the first one fails, the second one still runs. Using && makes the second command depend on the first. If the first command fails, the second will NOT run. Reference
You can use shell_exec() PHP function to run Shell Command directly in your script.
Syntax : string shell_exec (string $cmd)
Example :
$output = shell_exec('ls -lart');
var_dump($output); #Showing the outputs
You can use multiple conditions in a single command line.
Example :
$data = "rm a.txt && echo \"Deleted\"";
$output = exec($data);
var_dump($output);
if($output=="Deleted"){
#Successful
}
In above example "Deleted" string will assign to $output when the file deleted successfully. Otherwise the error/warning/empty string will assign to $output variable. You should make condition with $output string.
Here is the documentation of shell_exec()
Note : There will be a new line character of the function shell_exec() output.
If I understand your question correctly, you want to execute $command1 and then execute $command2 only if $command1 succeeds.
The way you tried, by joining the commands with && is the correct way in a shell script (and it works even with the PHP function exec()). But, because your script is written in PHP, let's do it in the PHP way (in fact, it's the same way but we let PHP do the logical AND operation).
Use the PHP function exec() to run each command and pass three arguments to it. The second argument ($output, passed by reference) is an array variable. exec() appends to it the output of the command. The third argument ($return_var, also passed by reference) is a variable that is set by exec() with the exit code of the executed command.
The convention on Linux/Unix programs is to return 0 exit code for success and a (one byte) positive value (1..255) for errors. Also, the && operator on the Linux shell knows that 0 is success and a non-zero value is an error.
Now, the PHP code:
$command1 = "ipcli -S 192.168.4.2 -N nms -P nmsworldcall ";
$command2 = "list search clientclassentry hardwareaddress 00:0E:09:00:00:01";
// Run the first command
$out1 = array();
$code1 = 0;
exec($command1, $out1, $code1);
// Run the second command only if the first command succeeded
$out2 = array();
$code2 = 0;
if ($code1 == 0) {
exec($command2, $out2, $code2);
}
// Output the outcome
if ($code1 == 0) {
if ($code2 == 0) {
echo("Both commands succeeded.\n");
} else {
echo("The first command succeeded, the second command failed.\n");
}
} else {
echo("The first command failed, the second command was skipped.\n");
}
After the code ends, $code1 and $code2 contain the exit codes of the two commands; if $code1 is not zero then the first command failed and $code2 is zero but the second command was not executed.
$out1 and $out2 are arrays that contain the output of the two commands, split on lines.
I'm not sure to know about simultaneous execution but I'm sure about one cmd dependent on another cmd execution action. Here I'm running single execution cmd first to clear all set path, second I've declared my file path, third I install angular cmd npm install.
$path = "D:/xampp/htdocs/tests/omni-files-upload/aa-test/src";
$command_one = "cd /";
$command_two = "cd ".$path;
$command_three = "npm install";
#exec($command_one."&& ".$command_two."&& ".$command_three);
I am unable to get php to show full results of my python script, only the last basic print statement is printed. What am I doing wrong here? Why is the php not showing the output from the python script?
php
$result = exec('python list.py');
echo $result;
list.py
import subprocess
print "start"
a = subprocess.Popen(["ls", "-a"], stdout=subprocess.PIPE)
a.wait()
result_str = a.stdout.read()
print result_str
print "stop"
the command line output for that python script is as below
start
...filename
...filename
...etc...etc
stop
The php output from executing the python script is only
stop
Thank you
You need to pass $result as a param into exec() otherwise you only get the last statement.
exec('python list.py', $result);
print_r($result);
This will get an array of output, $result[0] will contain stop and $result[sizeof($result)-1] will contain stop and everything in between will contain the rest of your program output.
exec will always return the last line from the result of the command. So, if you need to get every line of output from the command executed. Then, you need to write as below :
$result = exec('python list.py', $ouput);
print_r($output)
As per exec documentation
string exec ( string $command [, array &$output [, int &$return_var ]] )
If the output argument is present, then the specified array will be
filled with every line of output from the command. Trailing
whitespace, such as \n, is not included in this array. Note that if
the array already contains some elements, exec() will append to the
end of the array. If you do not want the function to append elements,
call unset() on the array before passing it to exec().
I want to process my access log in php - checking some IPs, which are leeching content and so on, everything in PHP, running as CLI. I tried to make following, but it never pass exec tail -f, so, actually I can not process the data. Any help appreciated.
$log = '/var/log/lighttpd/web.org-access.log';
$pipefile = '/www/web.org/tmp/fifo.tmp';
if(file_exists($pipefile))
if(!unlink($pipefile))
die('unable to remove stale file');
umask(0);
if(!posix_mkfifo($pipefile,0777))
die('unable to create named pipe');
exec("tail -f $log > $pipefile 2>&1 &"); //I tried nohup and so on...
//exec("varnishncsa $log > $pipefile 2>&1 &"); //will be here instead tail -f
echo "never comes here"; //never shows up
If possible, I want to do it just in PHP, no bash/tcsh scripting (I know how to do it using those).
Thanks.
If you want exec to start a background process, you will have to redirect its output.
Quote from the manual:
If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
Notice the full syntax description:
string exec ( string $command [, array &$output [, int &$return_var ]] )
Source: http://www.php.net/manual/en/function.exec.php
I'm running a simple command in a loop
the command itself is ffmpeg, but I do not believe it's related to the issue
so, I have:
exec($exec.' 2>&1', $output, $return);
if($return)
{
foreach($output as $line)
{
file_put_contents($log_file, $line, FILE_APPEND);
}
}
This way, if anything goes wrong with the command I can read the output in the log. It works, however $output contains the entire shell history of the command. To clarify: every time an error occurs, all output that was generated by the particular command (including hundreds of successful executions from throughout the day) is dumped to the file. What should be a 5 line error being written is instead the entire 1000+ line history. I used the exact same code on CentOS and it gave me the expected output of only the output generated by the instance most recently executed.
From the documentation:
Note that if the array already contains some elements, exec() will append to the end of the array. If you do not want the function to append elements, call unset() on the array before passing it to exec().
I can't explain why it worked differently on CentOS.
Code:
$exchangesnapin = "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010";
$output = shell_exec('powershell '.$exchangesnapin.';"get-mailboxdatabase" 2>&1');
echo( '<pre>' );
echo( $output );
echo( '</pre>' );
Result:
Name Server Recovery ReplicationType
---- ------ -------- ---------------
Mailbox Database 0651932265 EGCVMADTEST False None
Mailbox Database 0651932266 EGCVMADTEST False None
I tried with
echo( $output[1] );
The result was only a letter 'N'. I believe its taking the Name column but one character at a time.
$output[1] is 'N', $output[2] is 'a'.
Is there any way I can get the mailbox list into array?
you are trying to execute an external program (powershell) from PHP and have the output as an array.
In order to execute an external program in PHP, you could use:
exec() function
shell_exec() function
system() function
backtick operator
process control extensions
using process control extensions (PCNTL, popen) gives you more control, but takes more code and time. using the execution functions are simpler.
In this situation, using exec() could help you to have the output of powershell in an array whose each index is a line from the powershell output.
<?php
$output = array(); // this would hold the powershell output lines
$return_code = 0; // this would hold the return code from powershell, might be used to detect execution errors
$last_line = exec("powershell {$exchangesnapin} get-mailboxdatabase 2>&1", $output, $return_code);
echo "<pre>";
// print_r($output); view the whole array for debugging
// or iterate over array indexes
foreach($output as $line) {
echo $line . PHP_EOL;
}
echo "</pre>";
?>
Please note that (as the documentation says) if you only want to echo the output of powershell, you could use the passthru() function. using exec() uses memory to store the output of the external program, but using passthru would not use this storage, resulting in less memory usage. But the output could not be used for further processing, and is sent to the PHP standard output right a way.
In the end, please note that external program execution requires careful data validation to reduce the risk of unwanted system effects. Make sure you use escapeshellarg() on the data that constructs the execution command.