Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

While trying to determine the differences between .bashrc and .bash_profile I notice that .bashrc is never read, and that .bash_profile is only read from SSH, but not from PHP. This seems to contradiction to the information in man bash. Could someone explain to me why this works as it does? The server seems to be a CentOS 5 variant.

local$ ssh user@server
Last login: Wed Jan 23 23:21:23 2013 from 1.2.3.4

$ cat .bashrc
alias br='echo fromBR'
$ cat .bash_profile
alias bp='echo fromBP'

$ br
-bash: br: command not found
$ bp
fromBP

$ cat public_html/bashtest.php 
<?php
echo "hello\n";
echo shell_exec('bp');
echo shell_exec('br');
?>
$ php public_html/bashtest.php
hello
sh: bp: command not found
sh: br: command not found

$ wget server/bashtest.php
23:35:13 (759.55 KB/s) - `bashtest.php' saved [7/7]
$ cat bashtest.php 
hello!

So it seems that .bashrc is never read and .bash_profile is only read from the CLI (not from PHP either on the user's CLI nor through Apache). Furthermore, through Apache the "command not found" text isn't even returned!

Is this expected behaviour (i.e. am I misinterpreting man bash) or is something amiss?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

Well, for a start, PHP isn't doing shell_exec through bash in your case, it's doing it through sh. This is fairly obvious from the exact error message. I'm guessing that this is controlled by whatever shell is specified in /etc/passwd for the user that the web server is running as and shell_exec doesn't capture stderr, in combination with that when you run PHP from the command line it simply drops out to ${SHELL}. When launched as sh, bash turns off a number of features to better mimic the behavior of the original sh shell. Sourcing of .bashrc and .bash_profile almost certainly are among those, if for no other reason then because those files are likely to use bash-specific syntax or extensions.

I'm not really sure about the SSH case, but judging from the plain $ prompt, you might very well be running through sh there, which would likewise explain the behavior you are seeing. Try echo ${SHELL} to see what you really got dropped into; that should work on all shells.

That said, it seems to me like a really bad idea to depend on bash aliases from a PHP script. If what you want to do is too long to fit nicely in the shell_exec statement itself (which should only be used with great care), making a PHP function to create the command line from the parameters and calling that is almost certainly a much better approach, and it will work essentially regardless of which shell is installed, selected or how it is configured. Alternatively, consider calling an external script file, which can be written in bash and specify /bin/bash as its interpreter. But then your application will require that bash is installed (which it probably does already if it depends on bash aliases...).

share|improve this answer
    
Thanks. I actually trimmed the command prompt before the $ and cut out other irrelevant information. The issue that I'm dealing with is that the name of the Python executable changes while the system admin decides what version of Python are to be installed on the server, so I might have to change python to python3 to python3.0 or back again, or even wrap calls to python2 with python for older scripts. I suppose that these might be better of as wrapper commands in $HOME/bin then, or is that also a bad practice? –  dotancohen Jan 24 '13 at 11:03
    
define(PYTHON_INTERPRETER, 'python3.0'); ... shell_exec(PYTHON_INTERPRETER . ' somefile.py'); would seem to be one possible alternative. The define can be placed in some kind of configuration file which is required by each .php file that needs to call an external Python script. (ugh) Or just ask the sysadmin to put a symlink in some stable location and point it to whatever version of Python happens to be installed today. (/usr/local/bin/python pointing to /usr/bin/python today, /usr/bin/pyhon3.0 tomorrow, and /usr/bin/python2 the day after that.) –  Michael Kjörling Jan 24 '13 at 14:59
    
OUCH! If it was me, if they don't want to hire a sysadmin, I'd convince them to get a real web hosting account. There is a lot more to maintaining a publicly-accessible web server than installing whatever version of Python one feels like at the moment, and "whichever student is currently on duty" will almost certainly botch it sooner or later (probably sooner than later). Depending on where you are located it should be possible to establish a professionally managed web hosting account for a few USD/month or thereabouts. –  Michael Kjörling Jan 24 '13 at 15:08
    
This is a real webhosting account, my comment was probably a bit too deriding of people working at the budget webhost. Really, they only support Python 2.4 but they are trying their best to install Python 3.0 for this client. –  dotancohen Jan 24 '13 at 15:33
    
@dotancohen, why don't they install distribution packages for Python 3?! If they really don't understand the humongous amount of work required to maintain a random collection of software compiled from source working (let alone secure), I'd sugest running away as fast as your legs will carry you. –  vonbrand Jan 26 '13 at 6:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.