$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);
Related
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
I have this line of code to execute a background task (convert several pngs to jpg)
exec("nohup path/to/php path/to/convertToJpg.php >> path/to/convert_to_jpg.log > /dev/null &");
Now I am writing the convertToJpg.php script and I can't figure out how to output information from there so that it will be logged into the convert_to_jpg.log.
When I try to google it all I come up with is how to call a php script from exec or shell_exec, since the words used to describe the two situations is almost the same.
For Clarification
An extra quote got into my code when copying it over to SO. I have fixed it. In my original code the convertToJpg.php is being called as expected, confirmed by error_logs placed in it to check.
A couple answers have pointed to the $output argument in exec(). As I understand it, that totally defeats the purpose of shell redirection using the >> path/to/convert_to_jpg.log.
My question is not how to get the output from the exec() command, but what code do I use to actually output(verb) from the convert_to_jpg.log
More Clarification
If I call
exec("nohup path/to/php path/to/convertToJpg.php >> path/to/convert_to_jpg.log > /dev/null &");
or
$results = shell_exec("path/to/php path/to/convertToJpg.php > /dev/null");
echo $results;
or
$results = "";
exec("path/to/php path/to/convertToJpg.php > /dev/null", $results);
print_r($results);
It doesn't matter which one.
Here is convertToJpg.php
<?php
echo "Will this be in $results?"; // No, this did not end up in results.
error_log("error logs are being logged, so I know that this php file is being called");
//I have tested echo, but that does not work.
//What php function do I use so that a string will be captured in the $output of an exec() call?
?>
$output = "";
$return_var = "";
exec("nohup path/to/php path/to/convertToJpg.php >> path/to/convert_to_jpg.log > /dev/null &", $output, $return_var);
$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.
http://php.net/manual/en/function.exec.php
Ok, I figured it out!
To answer the question plain and simply, use either echo or print.
This was the first thing I tried, but it didn't work, which made me think it was some other function that I was supposed to call. (I obviously haven't worked with this much)
The real problem I was having was the > /dev/null, which was discarding all output. Once I deleted that, it fine. Explained here: What is /dev/null 2>&1?
I had at some point done a copy/paste without really understanding what that did...
And because I was blaming the wrong thing I ended up with this off base question.
I want to execute a cron job, but I recieved an e-mail that tells me:
No input file specified.
And I run the following cron command every day at 15:00
/usr/bin/php -q /home/popasur/public_html/analytics/savedata_script.php?paramz=savesmdata
If I remove the "?" I recieve an e-mail with the output, but I also recieve this warning:
Notice: Undefined offset: 1 in /home/popasur/public_html/analytics/savedata_script.php on line 15
$arguments = array();
if (is_array($argv) && !empty($argv)) {
foreach ($argv as $a) {
$a_explode = explode("=", $a);
$arguments[$a_explode[0]] = $a_explode[1]; //line 15
}
}
If you are using $argv, you should run your script like this:
php myScript.php arg1 arg2 arg3 ...
In this situation, you have:
$argv[0] // myScript.php
$argv[1] // arg1
$argv[2] // arg2
and so on.
Thats not usually how you pass parameters on the command line. The reason your script isnt running is that the shell is trying to find a file called /home/popasur/public_html/analytics/savedata_script.php?paramz=savesmdata
and what I think you want is :
/home/popasur/public_html/analytics/savedata_script.php paramz=savesmdata
Then perform whatever exploding you want on $argv[1]
(or use something like getopts to do it properly)
#!/bin/bash
cd /maintenance;
for (( i=1;i<1000;i++)); do
php -q dostuff.php $i
done
I use this shell script to call the dostuff.php script and pass the $i as an agrv to the script. The script connects to a webservice that returns results 50 items at a time. The $i value is the page number... I have no way to know how many times it needs to be called (how many pages) until I get a response code back from CURL inside that script that I test for. I need to pass my own response code back to the shell script to have it stop looping... it will never get to 1000 iterations... it was just a quick loop I made.
If I use exec("php -q dostuff.php $i", $output, $return_var) how do I tell the script to keep executing and passing the incremented $i value until my php script exits with a response code of 0?
There has got to be a better way. Maybe a while? Just not that good with this syntax.
I have to start at page 1 and repeat until page XXX incrementing by 1 each iteration. When there are no more results I can test for this in the dostuff.php and exit(0). What is the best way to implement this in the shell script?
Thanks!
You can check for the return value of the script, and break the loop if it isn't what is expected.
Usually a script returns 0 when it ran successfully, and something else otherwise, so if I assume your script respect this condition you could do:
#!/bin/bash
cd /maintenance;
for (( i=1;i<1000;i++)); do
php -q dostuff.php $i
if [ $? -ne 0 ]; then break; fi
done
On the other hand, if you want your script to return 0 if the loop shouldn't continue then you should do:
if [ $? -eq 0 ]; then break; fi
Edit: to take the comment into account to simplify the script:
If your script returns 0 when it shouldn't be called again, you instead do:
#!/bin/bash
cd /maintenance;
for (( i=1;i<1000;i++)); do
if php -q dostuff.php $i; then break; fi
done
As already suggested in the comments, you might get way better control if you dont wrap the php script inside a bash script but instead use php-cli as the shell script (PHP is kinda shell):
#!/usr/bin/php
<?php
for ($i = 0; $i < 1000; $i++) {
// contents of dostuff.php integrated
}
You might also be interested in using STDOUT, STDIN and STDERR:
http://php.net/manual/en/features.commandline.io-streams.php
I was trying to execute this command
echo exec("top");
and
echo exec("/usr/bin/top");
neither works (returns blank output)
does anybody know why?
Because top is an interactive program that is meant to be run on a terminal, not be executed from a script. You are probably want to run the 'ps' command with arguments which will sort output by cpu utilization.
http://www.devdaily.com/linux/unix-linux-process-memory-sort-ps-command-cpu
You actually can call top and echo its output. Code that worked for me:
passthru('/usr/bin/top -b -n 1');
-b - running in batch mode
-n 1 - only one iteration
It probably works, but exec() doesn't return anything. Read the Manual: exec()
$output = null;
exec('top', $output);
echo $output;
But you have another problem: top doesn't exit by itself. You cannot use it here, because you need to send the interrupt-signal (just realized: q is ok too).
One solution is to make top to stop after one iteration
$output = null;
exec('top -n 1', $output);
var_dump($output);
If you want to put it in a variable :
ob_start();
passthru('/usr/bin/top -b -n 1');
$output = ob_get_clean();
ob_clean();
I used:
$cpu = preg_split('/[\s]+/', shell_exec('mpstat 1 1'));
$cpu = 100-$cpu[42];
100% minus the idle time.