Fair warning; I don't even really know Ruby. I'm just hacking together some scripts that I was given and hoping they'll work together.
Background
I'm using Ruby to automate several tasks as an svn administrator, and one of the tasks that I'm trying to effect is making a web-form that will automate the creation of a repository.
The script I'm running is about 100-200 lines total, including the includes and things like that. I'm sure there will be other problems with the code, but presently, it's running into one problem.
The Ruby script itself works. My problem is that it doesn't work when I try to call it from a PHP script in a different directory.
The directory structure is like this:
Home
.www-docs
makeRepo.php
svn
createNewRepo.php
migrateOne.php // This has yet to cause a problem
RepoUtils.rb // Not currently causing a problem
Problem
The exact problem that I'm running into is that the Ruby script stops executing (and doesn't print an error message that I can echo in the PHP at a particular point in the code.
I'm calling the script as follows:
chdir("../svn");
echo exec("ruby createNewRepo.rb $name1 $name2 $num")
So, it's definitely calling the script. I put print points throughout the script, so I know it stops around here:
print "Point 1"
acl = File.new(##aclfile, "a")
print "Point 2"
##aclfile is an absolute path, not relative, so I don't think that alone is the problem.
The above code will end up printing Point 1 (and nothing that comes after that, either).
What am I doing wrong?
Thanks!
If it works when you run it by hand, but not through the PHP script, I'm thinking you've got a permissions problem. If the user that the web process is running as doesn't have access to the absolute path (or the path doesn't exist), you'll hit an error:
$ irb
1.8.7 :001 > File.new("/this/doesn't/exist", "a")
Errno::ENOENT: No such file or directory - /this/doesn't/exist
from (irb):1:in `initialize'
from (irb):1:in `new'
from (irb):1
1.8.7 :002 > File.new("/etc/passwd", "a")
Errno::EACCES: Permission denied - /etc/passwd
from (irb):2:in `initialize'
from (irb):2:in `new'
from (irb):2
1.8.7 :003 >
Check your permissions on the target directory and determine whether the web user has access to it. For security reasons, I won't tell you to change the web user's permissions or to change permissions on the target directory. You'll have to make that call yourself.
Related
$output = shell_exec('echo "php '.$realFile.'" | at '.$targTime.' '.$targDate.' 2>&1');
print $output;
Can someone please help me figure out why the above line isn't doing what it's supposed to be doing? The idea is for it to create an 'at' job that will execute a php script. If I switch to the user apache(which will ideally control the at function when the php file is complete) I can run
echo "php $realFile.php" | at 00:00 05/30/17
and it'll do EXACTLY what I want. The problem is in the above snippet from my php file it will not create the at job correctly. when I do a at -c job# on both of them the job made from my file is about a 3rd the length missing the User info and everything. It basically starts at PATH= and goes down. Doesn't include HOSTNAME=, SHELL=, SSH_CLIENT=, SSH_TTY=, USER=. I assume it needs most of this info to run correctly. The end output (below)is always the same though it just doesn't have any of the top part for some reason. Let me know if you need more info. I didn't want to paste all of my code here as it contains job specific information.
${SHELL:-/bin/sh} << 'marcinDELIMITER0e4bb3e8'
php "$realFile".php
marcinDELIMITER0e4bb3e8
It doesn't seem to be a permission issue because I can su to apache and run the exact command needed. The folder the files are located in are also owned by apache. I've also resulted to giving each file I try to run 777 or 755 permissions through chmod so I don't think that's the issue.
I figured out a coupe ways around it a while back. The way I'm using right now is an ssh2 connect to my own server as root and creating it that way. No compromise as you have to enter the password manually each time. Really bad work around. The main issue is that apache doesn't have the correct permissions to do everything needed for the AT job so someone figuring that out would be awesome. Another option I found on a random webpage would be to use sudo through the php script, but basically the same minus having to reconnect to your own server. Any other options would be appreciated.
Reading the manual and logs would be a good place to start. In particular:
The value of the SHELL environment variable at the time of at invocation will determine which shell is used to execute the at job commands. If SHELL is unset when at is invoked, the user’s login shell will be used; otherwise, if SHELL is set when at is invoked, it must contain the path of a shell interpreter executable that will be used to run the commands at the specified time.
Other things to check are that the user is included in at.allow, SELinux is disabled and the webserver is not running chrrot.
I am trying to build a small custom task scheduler. Basically the idea is I have cron run my process script, which looks in the database and finds any scheduled tasks that are ready to run, and runs them. So I think the best way to do this would be to try to launch the tasks "in the background" by way of shell_exec and using > /dev/null, which I understand makes it so the initial script (the process script) doesn't wait for the task scripts to complete.
So first, if there is a better way to achieve this, I'm open to suggestions. Though note I am on php 5.3 so there may be some options in 5.4 and up that I don't have access to :(
However here's the question at hand:
I am testing on WAMP on my windows machine and I am trying to make a call that looks like this:
shell_exec("php $path$base_url$querystring > output_test.txt 2>&1 &");
$path is the full windows path to the script
$base_url is the base url of the script I am calling
$querystring is of course the query string being passed to the task script
I am also outputting to output_test.txt which creates such file in same directory, where I get the following error:
Could not open input file:
C:\xampp\htdocs\email\batch_email_send_u2u.php?dealer=7
Yes I realize the path references an xampp installation, but that is not the issue - all the wamp files are executing from there and everything else has worked like this for years - it was just set up this way to support a legacy setup.
It seems to me shell_exec is locating and running php, it's just that it can't open the referenced script. Can't figure out why.
Also I need to eventually get this working on a real linux server so any advice on how to make that happen would be greatly appreciated!
Found a solution! Special thanks to dan08 for getting me set on the right path.
Ultimately I found the answer in this thread: Pass variable to php script running from command line
I ended up using the argv[] array as described in that post and with a little tweak to the script I'm calling it works like a champ now.
I've got some PHP code that I want to run as a background process. That code checks a database to see if it should do anything, and either does it or sleeps for awhile before checking again. When it does something, it prints some stuff to stdout, so, when I run the code from the command line, I typically redirect the output of the PHP process to a file in the obvious way: php code.php > code.log &.
The code itself works fine when it's run from the shell; I'm now trying to get it to run when launched from a web process -- I have a page that determines if the PHP process is running, and lets me start or stop it, depending. I can get the process started through something like:
$the_command = "/bin/php code.php > /tmp/code.out &";
$the_result = exec($the_command, $output, $retval);
but (and here's the problem!) the output file-- /tmp/code.out -- isn't getting created. I've tried all the variants of exec, shell_exec, and system, and none of them will create the file. (For now, I'm putting the file into /tmp to avoid ownership/permission problems, btw.) Am I missing something? Will redirection just not work in this case?
Seems like permission issues. One way to resolve this would be to:
rename your echo($data) statements to a function like fecho($data)
create a function fecho() like so
.
function fecho($data)
{
$fp = fopen('/tmp/code.out', 'a+');
fwrite($fp, $data);
fclose($fp);
}
Blurgh. After a day's hacking, this issue is finally resolved:
The scheme I originally proposed (exec of a statement with
redirection) works fine...
...EXCEPT it refuses to work in /tmp. I
created another directory outside of the server's webspace and opened
it up to apache, and everything works.
Why this is, I have no idea. But a few notes for future visitors:
I'm running a quite vanilla Fedora 17, Apache 2.2.23, and PHP 5.4.13.
There's nothing unusual about my /tmp configuration, as far as I know (translation: I've never modified whatever got set up with the basic OS installation).
My /tmp has a large number of directories of the form /tmp/systemd-private-Pf0qG9/, where the latter part is a different set of random characters. I found a few obsolete versions of my log files in a couple of those directories. I presume that this is some sort of Fedora-ism file system juju that I will confess to not understanding, and that these are orphaned files left over from some of my process hacking/killing.
exec(), shell_exec(), system(), and passthru() all seemed to work, once I got over the hump.
Bottom line: What should have worked does in fact work, as long as you do it in the right place. I will now excuse myself to take care of a large bottle of wine that has my name on it, and think about how my day might otherwise have been spent...
I have a php script that carries out a trace route without using system(). It uses SOCK_RAW and ICMP.
I have managed to get this script to run with out been a root user or changing anything in sudoers by using CAP_NET_RAW.
The thing is, the scrip only works when called through the shell, not through the browser. When I go through my browser I get the error: socket_create(): Unable to create socket [1]: Operation not permitted . So something is going a miss here.
After googleing and googleing I am unable to work out why the same script is not working when called through apache. Do I need to add CAP_NET_RAW to an apache config file as well?
Any advice on this would be very much appreciated.
Jason
Typical Apache + PHP installations run under a separate system user (usually www-data). My guess is that this pseudo-user is heavily restricted. Try executing from the shell as the www-data user - it should fail, if I'm right.
I have tried calling a windows program several ways and I have gotten the same result each time.
The program opens up on my machine (without a GUI) but never closes each means that the browser is forever loading.
Though when executing the query string manually through the command line prompt the program closes. Not only that, but the program doesn't actually execute
(it is just launched i.e. there aren't any results).
I just want to know the proper way of starting a program with switches through PHP.
Here is the query string that works (closes the program after executing):
"C:\Program Files (x86)\Softinterface, Inc\Convert PowerPoint\ConvertPPT.exe" /S
"C:\Users\Farzad\Desktop\upload\test.ppt" /T "C:\Users\Farzad\Desktop\upload\test.png" /C 18
If the program never closes, then PHP can't return a value from exec(). The program must close. Chances are there is a problem accessing your files on your desktop in this manner. It will be executed with whatever permissions the webserver has defined.
http://php.net/manual/en/function.exec.php
You might consider the advanced functionality of proc_open(). It will give you access to all the necessary pipes, but I don't think that will help you in this situation.
If the target directory on your Windows machine is C:\Program Files (x86)\Softinterface, Inc\Convert PowerPoint\ConvertPPT.exe, you need to double-quote the directories that have space character within them.
To translate it into php terms, it should be like this:
$directory = 'C:\"Program Files (x86)"\"Softinterface, Inc"\"Convert PowerPoint"\ConvertPPT.exe';
$command = $directory . ' enter your arguments here';
exec($command, $output, $return_var);
// if $return_var == 0, you hit the jackpot.
The physical directory where your Windows desktop is stored belongs to your user profile folder. That means that other users (including the one Apache runs as, which is typical "Local System") won't have the appropriate permissions to read and write files on it. While you can adjust your Apache set-up to make it run with your own user, Farzad, it's more common to put web applications in an entirely different directory tree. It may happen that ConvertPPT.exe just stalls because it's trying to write a file at a location where it's not allowed. I suggest you create a top folder directory and make sure it's world-writeable (once finished, you can tighten these permissions if you like).
Once you discard (or confirm) that the issue is caused by lack of appropriate credentials, make sure you are escaping your command and arguments properly. See this link:
http://es2.php.net/manual/en/function.exec.php#101579
One more thing you can try is to close PHP sessions before issuing the call to exec():
http://es2.php.net/manual/en/function.exec.php#99781
You have probably run into this bug: http://bugs.php.net/bug.php?id=44994
which has been bothering me for ages, even today, on PHP 5.3.5.
It seems like there is some kind of deadlock between the error output of the program and the apache error log file handle into which the program is redirected to write its stderr output, making the program be stuck for ever until the apache processes are killed.
Also, when using passthru, or system, or the backtick operator, there's an intermediary "cmd.exe" process that is used to run the program in an invisible console, and I have seen this cmd process getting stuck without even running the program.
I don't really have a solution as of now, and it seems the bug, even though reproduced by many people, hasn't been resolved.