简体   繁体   中英

php exec bash scripts : No such file or directory

I have a few bash and perl scripts which has been asked to be made executable through a web based interface. Nothing fancy, just for easy access. PHP seemed to be the quick and dirty solution for the purpose [through exec() ]. So I turned off the safe mode in php.ini and tried

$output = array();
exec('/var/www/vhosts/default/htdocs/scripts/RUN.sh',$OUTPUT);
print_r($output);
var_dump($output);

Now whatever files are accessed in the RUN.sh script (accessed though a relative path) are not found. Is there any way of getting this to work without giving complete path to every single redirect (or any file for that matter) that is being accessed in the scripts?


After applying the accepted solution:

Say one line form the script:

time python idsplitter.py OUTPUT/TMP/tokens OUTPUT/token_splits
echo "done"

While the time -s output gets pushed to error_log file, "done" is never passed to the $OUTPUT array. The returned value in the third argument to exec(), when printed on page gives 0 .


Update: time command puts it out to stderr so if do `

t=`time some_command 2>&1`

then also nothing gets stored in t. So that makes sense. Thanks for the help everyone ...

Change the current working directory as part of the script itself.

Your working directory, from the perspective of the RUN.sh script, isn't what you think it is. Therefore, relative paths in the script don't point where intended.

To fix it you need to force the current working directory to be the one that works with the relative paths. So, either:

  • use absolute paths, or
  • change the current working directory via calling cd [/absolute/path] in the RUN.sh script, to force it to be correct.

Can you execute a chdir(2) call in your PHP script immediately before your exec() call to get the results you want? Or would that upset your PHP interpreter too much? (With CGI scripts, it'd be no problem at all; but FastCGI or similar mechanisms might not like you much.)

Relying on relative pathnames is already a bit quick-and-dirty, and this just perpetuates it. Perhaps fixing the scripts is a better approach.

Edit

I'm stuck with the output getting redirected to the error_log rather than to the php page, any idea why?

That is a symptom of a program sending its output to standard error, rather than standard out.

But there is a complication with time -- normally, when you run time , you get the bash(1) built-in time reserved keyword. I cannot find any easy way to ask bash(1) to send the time reserved keyword output to a different file descriptor. However, you can also run the time(1) program (which is in /usr/bin/time ). By default, time(1) 's output goes to standard error, but you may redirect output as you wish:

$ /usr/bin/time echo hello
hello
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 2528maxresident)k
0inputs+0outputs (0major+206minor)pagefaults 0swaps
$ /usr/bin/time echo hello > /dev/null
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 2544maxresident)k
0inputs+0outputs (0major+207minor)pagefaults 0swaps
$ /usr/bin/time echo hello > /dev/null 2&>1
$ 

To get the time(1) output to look more like the time shell built in keyword output, you can use the -p option:

$ /usr/bin/time -p echo hello
hello
real 0.00
user 0.00
sys 0.00

So, replace the line:

 time python idsplitter.py OUTPUT/TMP/tokens OUTPUT/token_splits 

with the line:

/usr/bin/time -p python idsplitter.py OUTPUT/TMP/tokens OUTPUT/token_splits 2>&1

and you ought to be good to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM