How to find if command executed in exec command fails? - php

I need to know that If I call a php script execution command through exec command and the script execution fails due to any reason say "file not found" , then how can I find it out.
I have following command :
$cmd="php testfile.php" ;
$outputfile="testoutput.txt";
exec(sprintf("%s > %s 2>&1 & echo $!", $cmd, $outputfile),$pidArr, $status);
exec command return -1 in case of error but in this case exec is executing successfully ie $status is coming 0 in my case but the "php testfile.php" command is failing, the output is getting in testoutput.txt.
But I need to know the way so that I can identify it after exec if the command is failed.
I could think of the option of reading testoutput.txt and grep for fail or error word, but I dont think it is reliable.
Thanks in advance!

You can receive the output result of the exec function by passing an optional second parameter:
So you could execute the exec() with that 3rd arg, then check if it is non-zero for an error condition.
exec("blah blah blah", $output, $result);
if($result > 0)
{
die('error message here');
}
If you don't find the error through that second parameter, you can search for the error log of apache, for example in Ubuntu Server 12.10 through the command $ tail /var/log/apache2/error.log
let me know if i can help you more.

http://php.net/manual/en/function.exec.php
exec(sprintf("%s > %s 2>&1 & echo $!", $cmd, $outputfile),$pidArr, $status);
$status=0 if no errors, > 0 if errors

Related

How to show complete output even though it's error?

I have following php script in which I am trying to execute a command on Windows and print it's output. I have tried system(), shell_exec(), passthru() and exec().
$cmd = $_POST['cmd'];
$result = array();
exec($cmd, $result);
foreach ($result as $line ){
echo $line."<br>";
}
exec($command, $array) is the closest to my expectation of printing everything when a command is executed. I wish to print everything even though it's an error. But it only prints when command is executed successfully.
How to achieve it ?
$result only contains the standard output of the command, but error messages are usually written to standard error. You need to redirect stderr to stdout when running the command.
$cmd = "$cmd 2>&1"
exec($cmd, $result);
In the shell, what does " 2>&1 " mean?

Return code of exec is wrong when using 2>&1 to have the error output

I'm using exec to execute some unix commands, like this one :
exec('cd /var/www/html/ && export PATH=$PATH:usr/loval/bin/npm && npm run dev; 2>&1', $output, $return_code_npm_run_dev);
I need to have the output with the error, so I put 2>&1 in the end of the command. But, when I do this, the return code (here : $return_code_npm_run_dev) is always 0. When I remove 2>&1, the return code is what I want (1 if something is wrong, 0 if all is ok.)
My questions are : why exec send me 0 when I redirect stderr ?
Is there another way to have the good return code and the stderr printing ?
Get rid of the semi-colon here:
npm run dev; 2>&1

How do you call python command "workon" from PHP exec?

I am running a PHP script from the CLI. In that PHP script I would like to execute a few commands from the command line using system(). Perhaps this isn't the right tool for the job, and I could probably just wrap the PHP script in a shell script, but I want to know if it's possible to do completely within the PHP script.
When I do this in a terminal it works fine:
user#host:~$ workon pootle
(pootle)user#host:~$
However this doesn't work from PHP (being executed as the same user).
#!/usr/bin/env php
<?php
system('workon pootle'); // sh: 1: workon: not found
system('/bin/bash workon pootle'); // /bin/bash: workon: No such file or directory
system('/bin/sh workon pootle'); // /bin/sh: 0: Can't open workon
I notice that the output for the last two is exactly the same as when executing by a terminal, but the first one is different. I thought it might be an alias, however it doesn't appear to be. alias | grep -i workon shows no output.
I also compared all of the environment variables returned from command line env and PHP system('env'), and all but _ are exactly the same, including SHELL=/bin/bash.
The output of which workon executed by the terminal is empty.
Edit
Maybe I'm getting somewhere with this.
user#host:~$ type workon
workon is a function
workon ()
{
typeset env_name="$1";
if [ "$env_name" = "" ]; then
lsvirtualenv -b;
return 1;
fi;
virtualenvwrapper_verify_workon_home || return 1;
virtualenvwrapper_verify_workon_environment $env_name || return 1;
activate="$WORKON_HOME/$env_name/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate";
if [ ! -f "$activate" ]; then
echo "ERROR: Environment '$WORKON_HOME/$env_name' does not contain an activate script." 1>&2;
return 1;
fi;
type deactivate > /dev/null 2>&1;
if [ $? -eq 0 ]; then
deactivate;
unset -f deactivate > /dev/null 2>&1;
fi;
virtualenvwrapper_run_hook "pre_activate" "$env_name";
source "$activate";
virtualenvwrapper_original_deactivate=`typeset -f deactivate | sed 's/deactivate/virtualenv_deactivate/g'`;
eval "$virtualenvwrapper_original_deactivate";
unset -f deactivate > /dev/null 2>&1;
eval 'deactivate () {
# Call the local hook before the global so we can undo
# any settings made by the local postactivate first.
virtualenvwrapper_run_hook "pre_deactivate"
env_postdeactivate_hook="$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postdeactivate"
old_env=$(basename "$VIRTUAL_ENV")
# Call the original function.
virtualenv_deactivate $1
virtualenvwrapper_run_hook "post_deactivate" "$old_env"
if [ ! "$1" = "nondestructive" ]
then
# Remove this function
unset -f virtualenv_deactivate >/dev/null 2>&1
unset -f deactivate >/dev/null 2>&1
fi
}';
virtualenvwrapper_run_hook "post_activate";
return 0
}
bash /usr/share/virtualenvwrapper/virtualenvwrapper.sh workon
I found this by installing virtualenvwrapper and then i ran
env | grep VIRTU
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
VIRTUALENVWRAPPER_SCRIPT=/usr/share/virtualenvwrapper/virtualenvwrapper.sh
VIRTUALENVWRAPPER_HOOK_DIR=/root/.virtualenvs
_VIRTUALENVWRAPPER_API= mkvirtualenv rmvirtualenv lsvirtualenv showvirtualenv workon add2virtualenv cdsitepackages cdvirtualenv lssitepackages toggleglobalsitepackages cpvirtualenv setvirtualenvproject mkproject cdproject mktmpenv
and saw VIRTUALENVWRAPPER_SCRIPT ... pretty easy to figure out from there
To be able to execute the virtualenvwrapper functions, we need to first source the virtualenvwrapper.sh file. To find the location of that file, in a terminal execute:
which virtualenvwrapper.sh
If that doesn't produce any output, use find to find it.
find /usr/ -name "virtualenvwrapper.sh"
For me, the location was /usr/local/bin/virtualenvwrapper.sh
When PHP does system calls, it uses sh:
<?php
system('echo $0'); // echoes 'sh'
However the virtualenvwrapper.sh script fails when being executed with sh, so we need to use bash instead.
Another thing to note is that PHP system calls are separate subshells from each other, so if you do:
<?php
system('FOO=BAR');
system('echo $FOO');
This prints out an empty line. Where as the following prints BAR:
<?php
system('FOO=BAR && echo $FOO');
Therefore, we need to:
Use bash instead of sh
Source the virtualenvwrapper.sh
Execute workon to change working virtual environments
Execute any other commands needed
Do all this in one single line
This is what I came up with and appears to be working correctly:
<?php
$commands = [
'source /usr/local/bin/virtualenvwrapper.sh',
'workon pootle',
'pootle update_stores --project=AIWeb',
];
system('/bin/bash -c "'.implode(' && ', $commands) .'"');

running a script exec command from php

I have an application where I need to run a PHP script by exec() function of php.
"php
/var/www/server/data/scripts/ThreadHandler.php
145596 >
/var/www/server/data/logs/threads/thread.145596.log
2>&1 &"
also tried
"php
/var/www/server/data/scripts/ThreadHandler.php
145596 >
/var/www/server/data/logs/threads/thread.145596.log
2>&1 "
I am running above command with exec() function of PHP, but it is not getting run, I can't track any error. please suggest any change.
try
passthru('php -f /var/www/server/data/scripts/ThreadHandler.php 145596 >
/var/www/server/data/logs/threads/thread.145596.log 2>&1');
Also, try to run it from linux command line
Try defining $output and $return_var arguments for exec and print their values :
$output = array();
$rv = null;
exec("your command", $output, $rv);
print_r($rv);
print_r($output);

Apache permissions to execute the exec function

I've been trying to run this php code on CentOS:
<?php
$command = "diff file1 file2 > file3";
exec($command, $output, $error_code);
if ($error_code != 0) {
echo "Error: $error_code";
}
?>
And it always echoes "Error: 1". Error 1 is "Operation not permitted" http://www.pegasoft.ca/resources/boblap/99_b.html. It looks like apache has no permissions to do certain things, right? How can I fix that?
I think it's because you're not using the right command. You're running $command like in a terminal, so you need to add a command indicating that you have permission. I think that on CentOS it's su. In Ubuntu, for example, you would do sudo -command-.
So try to add su before diff.
Edit:
You should check here for proper usage of su:
http://wiki.centos.org/TipsAndTricks/BecomingRoot
Oh >____<
I had this line at the end of my script:
exec("rm -f /var/local/out/upload/example_word/word/diff.diff");
The file was created and then deleted... That's why I could never see it. Sorry.

Categories