I have two remote servers that need to have a certain codebase in sync. I have it all set up on the first, but while setting it up on the second, I ran into a problem:
They don't have hg installed in the same location. I can't just run hg <command> because it returns the error:
sh: hg: command not found
So I had been using the full path, but that won't work with two separate hg locations.
I thought it would be clever to run which hg and use the path from the response, so here's the new code:
$hg = trim(`which hg`, "\n");
$output = `{$hg} pull -u`
But $hg is NULL, so that doesn't work! I can ssh into the 2nd server and see that which hg definitely does work. I even appended 2>> path/to/log to see if there were any errors with the which command, but there was not. I made sure it was writing to the log, so it wasn't related to that.
I am not running in safe mode, and I am definitely allowed to run shell_exec because other commands work.
I know I could just create a symlink so they both had the same path and just hardcode the path, but it's driving me crazy why shell_exec('which hg') isn't working!!!
which hg will only work if hg is already in your path, otherwise it will return the empty string.
Obviously this is not what you want, since if it were already in your path, you could just use hg.
If you're using many machines with different configs, you could just create a bin directory in your home directory, add it to your path and make links to the commands you need in that directory. That will allow you to use the same commands on all machines.
For PHP, you'd need to put it in a directory accessible to the web server (but preferably outside the document root), besides that, you can use the same technique there by giving an absolute path to the common directory where you created your links.
try
shell_exec('/usr/bin/which hg');
instead. $PATH may not be set and that is a typical location of which
Related
In my PHP file, I ran var_dump(exec('echo $PATH')); and got /usr/bin:/bin:/usr/sbin:/sbin
Then I ran echo $PATHin terminal, I got /Library/PostgreSQL/9.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
How can't I add $PATH variable to Xampp?
Your $PATH represents folders that the system is already aware of, and can access the contents directly. That is all it does. This is a system level thing, not a PHP thing, but anything in your $PATH is already available to PHP.
You should be aware that Mac OSX and Linux both run on a UNIX command line, and it works exactly the same on both.
Say for example I have a directory like:
/usr/local/foobar
I want to use foobar for something. If it is not in my $PATH, then I have to access it with
/usr/local/foobar
If it is in my $PATH, then I can access it with
foobar
The $PATH is separated by : so if my $PATH is /usr/local:/usr/bin, then I have two folders that are known to the system automatically, being:
/usr/local
/usr/bin
And anything in those can be directly accessed.
If I want a list of them in PHP, I would use the following to get a list of the folders:
$path = explode(':', `echo $PATH`);
On the command line, you just do echo $PATH
If you need to add a new folder to it, you would do (from the command line) either:
export $PATH=$PATH:/path/to/new/folder
or
export $PATH=/path/to/new/folder:$PATH
I would use the first one if I want the new folder to be at the end of the results, which would be the case if I were overriding an existing value in it with something else I want it to use instead. I would use the second option if I want my new folder to be put at the beginning of the list.
DO NOT FORGET TO PREFIX OR SUFFIX THE NEW VALUE WITH $PATH, OR YOU WILL LOSE EVERYTHING YOU ALREADY HAD AND PROBABLY BORK YOUR SYSTEM
If you add stuff to the $PATH, you also need to source your .bashrc file to tell the system to reload the path and be aware of the changes, like this:
source ~/.bashrc
The reason your path is different, is because from the command line, you are seeing the $PATH for your user, and from the script, you are seeing the $PATH available to the user the webserver is running under. To resolve this, you have two options:
Run the webserver as your user (which is a bad idea for security reasons, so I'm not going to bother explaining how to do this)
Edit the .bashrc for the user that the webserver runs under (which is a better option)
First, in your script, you want to do
echo `whoami`;
This will tell you what user the webserver is running under.
You can then use sudo su webservername (use the value you got from the above command in place of webservername), then use the above export $PATH=... and source ~/.bashrc to fix the path of the webserver account as needed, then exit to go back to your own account, or just close the shell window. Then go back to your script and do
var_dump( explode(':', `echo $PATH`) );
and you should see the correct values (in addition to whatever other folders the webserver had that you do not on your own $PATH).
You can also use vim or vi to accomplish this, by doing
vi ~/.bashrc
and put one folder per line in that file, then save and close, and do source ~/.bashrc as you normally would to reload it. If you are not familiar with vim, use the export approach instead.
I have run into a truly strange issue for which i have no explanation whatsoever.
After setting up OS X Yosemite and my local dev environment using XAMPP, i installed ImageMagick through MacPorts. All is well, it runs perfectly fine on the commandline.
However, when executed through Apache and called through PHP, i get no output from it whatsoever.
I have done extensive research and found a variety of approaches:
Setting the path environment variable in Apache (which i tried)
Using an absolute path to the executable (which i do)
Checking if exec() is listed as a disabled function (which it is not)
Checking if convert is even callable, as in executable (which it is)
I even went as far as copying the convert executable to the local project root directory and trying to exec('./convert'); but to no avail. I always receive absolutely no output from that call. Not even an error message. Needless to say, when i run the same thing through the Terminal, it works fine.
I also tried:
Calling exec('ls'); to see if anything comes up at all (yes it does, that works fine)
Calling exec('which convert');, where i get no result at all - the call returns nothing
Calling exec('which ls'); to double-check if the problem was with which - but which ls works fine and gives me /bin/ls as a response.
Providing chmod 0777 to the executable - to no avail
Regardless from what i try or do, convert remains entirely untouchable to PHP/Apache.
Can anyone tell me why that is and how to remedy it?
Checking the Apache error logs, i found the following message:
dyld: Library not loaded: /opt/local/lib/libfreetype.6.dylib
Referenced from: /opt/local/bin/convert
Reason: Incompatible library version: convert requires version 18.0.0 or later, but libfreetype.6.dylib provides version 15.0.0
Research showed that there is a common approach changing some environment path variable that applies to Apache and its subsidiary processes while running. However, since i did not want to fiddle around like that, i went for a somewhat more raw approach:
I opened a terminal and went to the very root directory of my system. There i ran:
find . -name "libfreetype.6.dylib"
This gave me all the libfreetype.6.dylib files that were available on my system. One of them was in the XAMPP lib directory, another one was in /usr/local/lib.
I backup up the file in the XAMPP directory and then copied the one from /usr/local/lib there.
I then tested convert again through Apache and was given another, quite similar error message relating to libexpat.1.dylib. For that i repeated the copying process as above. Afterwards, convert was executable through Apache and the problem was solved.
When you run scripts and programs via your web server, they are being run by a different user. In Macs this is usually _www. The convert application can't be found because the path to its executable file (probably /usr/local/bin) isn't included in the $PATH environment setting for this user.
The simplest solution is just to prefix the command with the path to convert, i.e., exec('/usr/local/bin/convert ... ');
As a customer in Plesk, I am attempting to run:
php -q /httpdocs/_external/export/test.php
From this tutorial: http://daipratt.co.uk/crontab-plesk-php/
I'm receiving the error
"php: command not found"
Is there something I need to enable from the main user or a different command I would need to use to run the script?
(also tried /bin/php with no luck, there is no php file in that dir)
"which php"
-/usr/bin/php
(when I use this dir I also get "no such file or dir" I guess since when I use / it's pulling from the customers root not the server root)
This answer will help you. My understanding is that Cron runs everything relative to itself, so you should always use absolute paths when running something from Cron.
Good luck, and happy holidays!
i am trying to run this piece of php code on my server:
<?php
$cmd = 'echo "this is a test" > /home/ubuntu/scripts/test_file';
echo exec($cmd);
?>
From my understanding it should add the piece of text to the file test_file . The file exists in the appropriate location and i have tried chmod 755 and chmod 777 on the php file. But i dont see the text being added to the text_file . I tried running the linux command directly on the server and it works. Could some one tell me what i am doing wrong?
Also, i am trying to create a virtual host file on the server through a php script. Rather than running the commands through php exec() , i thought it would be better to run a shell script, with the shell script reading the required parameters from a text file and setting the directory path in the virtual host file. I am new to linux, is this a good approach or is there a better way in going about this? All this is being done to setup a magento based site programatically. Thanks.
Your code is OK. The problem probably either lies with your php being in safe mode (though it's deprecated, see link) or with file/directory permissions.
No need to give the file permissions 0777 since that makes the file executable, 0666 should suffice. It is not enough however for the file to have the right permissions, each directory on the path must be traversable. Try a different directory to which the user with whose privileges the php code runs has access, /tmp is a good start.
General way to debug problems like this is to execute a different command which gives you extra information about the context in which echo is executed, e.g.
<?php
echo exec("id");
echo "<br/>";
echo exec("ls -l /home/ubuntu/scripts/test_file");
?>
(remember exec() only returns the last line of command's output, these display just one line though). These commands will tell you the user which runs the code and whether they can see the file at all.
As the comment already said: this is actually bad way to accomplish what you're trying to do, as writing Apache configuration based on user input through web could open you up to multiple issues.
What you might consider, is to have the PHP side write the required information to a file, or a database, which is then polled every now and then via a cron script or similar by a different process that does the actual configuration changes. This eliminates the need to exec() from PHP (which is always bad). With this, your process that runs PHP wouldn't need to have write permissions to important system files.
Normally google is my friend for these kind of newbie problems, and I'm pretty proud of myself learning as I go without really needing to ask any questions in terms of PHP stuff, but this one's got me stumped. Trying to install a version of PEAR that supersedes my host's copy, which is hideously outdated. Apparently "pear's binary (bin) directory should be in your PATH variable." I don't know what that means or how to edit it, and supplementary to that, wether that will actually solve my problem of an outdated version of pear being on my root server. Any advice in either of these areas would be greatly welcomed, thank you.
Actually, they are talking about the OS's PATH environment variable, not PHP's include path (binaries [bin] are run by the OS, not parsed by PHP) Unfortunately, since you are in a shared hosting environment, you cannot change this environment variable in a permanent fashion. If you do have shell access though, you can modify your .profile file set the PATH variable.
You can use getenv() and putenv() to retrieve and set the PATH variable, but this will be reset on each script run.
That said, you do not need the PATH variables set to use PEAR. If you have a PEAR install on your development computer, you can upload the pear folder onto your host and modify the include_path at runtime to point to your own "install" using set_include_path()
$pearInstallPath = realpath('./pear/packages');
set_include_path('.' . PATH_SEPARATOR . $pearInstallPath);
The PATH variable that's being referred to doesn't actually have anything to do with PHP.
The PATH is the list of directories that your shell will look in to find a command you run on the command line. So, this is talking about making the shell find the right path when you run pear on the command line.
Assuming you're using bash, one way to change this is to add a line like
export PATH=/path/to/pear/bin:$PATH
to a .bash_profile or .profile file in your home directory.
Try this
getenv('PATH'); // for get PATH varibale
putenv('PATH=./'); // for set path variable
getenv, putenv