The Dev Pages

A knowledge base for simple (and beyond) web applications development

Archive for the ‘Linux’ Category




Note: If you have a one-off php script that just needs to shoot out emails, consider using the PEAR Mail class, or something similar. You can just pass it an SMTP server (e.g. that of your gmail account) with credentials (e.g. your gmail login) and it will work swell. See http://email.about.com/od/emailprogrammingtips/qt/PHP_Email_SMTP_Authentication.htm

Note 2: This was done on an ubuntu server using postfix. This assumes you have postfix or sendmail installed on your server. On ubuntu you just do a ’sudo apt-get install postfix’ (or sendmail). To configure your MTA (Mail Transfer Agent e.g. Postfix, sendmail, etc.) to be secure, you’ll need to take additional steps, beyond the scope of this article. If you’re not concerned about the contents of you’re email being sniffed out, you’re probably ok if you’re just using outbound mail (a null client) with no smtp server listening for incoming traffic on port 25. I personally don’t care if a comment from someone using my website is emailed to me in plaintext (but maybe they would). See http://www.n8williams.com/devblog/linux/using-postfix-on-linux-for-sending-only-outgoing-messages for postfix null client setup for just outgoing mail. You can do the same with sendmail, and even kill the sendmail daemons.

Open your php.ini file (ubuntu: /etc/php5/apache2/php.ini) and find the line that says:

; For Unix only. You may supply arguments as well (default: “sendmail -t -i”).
;sendmail_path =

Change this, by uncommenting out the second line, to:

; For Unix only. You may supply arguments as well (default: “sendmail -t -i”).
sendmail_path = /usr/sbin/sendmail -t -i

Where /usr/sbin/sendmail may be a different path for your linux distro. To find it you can issue ’sudo find / -name sendmail’ (note this does a recursive find starting at the root dir so it may take a little while, 7 seconds for me. Ctrl-C to cancel out of it when it finds it). the -t -i options have something to do with using email headers to determine who the email is from, and ignoring weird lines with a period. All I know is it has worked better with these flags. You can research them if you want.

Now here’s the crazy thing that I failed to get at first. If we’re using postfix, then why the hell are we dealing with sendmail_path? Well it turns out that sendmail_path is a common php.ini option, and the sendmail binary is commonly used by all sorts of things. So postfix, when installed, makes a sendmail binary called /usr/sbin/sendmail to be a sort-of backwards compatible sendmail interface for things that expect sendmail (which has been around for a while). So even though your calling upon a binary called sendmail, this is a postfix file. This confused me to no avail when I had installed sendmail first, than uninstalled it with the package m anager, and installed postfix. I was failing to understand why the uninstall didn’t remove the sendmail binary until I realized it was actually a postfix file after reading http://www.postfix.org/sendmail.1.html.

Now restart apache/php and the mail function should work. Let’s hope. There’s a million cluttered google results about all the various reasons why mail() runs, and may hang, but no email gets sent. One key is reading your logs. Get familiar with the mail log. On ubuntu this is /var/log/mail.err, etc.




Summary: What you want is to set up a null client. http://www.postfix.org/faq.html#null_client See my notes below for what constitutes an ’smtp server entry’.

So for my local dev environments I’ve been in the habit of setting up php’s mail function to work by doing a ’sudo apt-get install sendmail’ and editing the php.ini to point the sendmail_path to /usr/sbin/sendmail. (I’d recommend this procedure only if you’re working locally and don’t plan on opening port 25 to anything public, won’t want to mess with domain names, and won’t be dealing with mx records, etc.).

Well when I actually had to setup a server with a public domain, and needed emails to work efficiently from php with a qualified domain while worrying about port 25 being secure, I was in for some fun. For starters I’d recommend postfix over sendmail. Much easier to configure. Sendmail has many more config files, and you have to re-compile some of them after edits, etc. So once you have postfix installed, if you just want to send outgoing emails, then you can increase security and reduce overhead by making postfix not listen on the SMTP port. I wanted postfix as an smtp client only. With sendmail you can do this, and even kill all the daemons. With postfix you still need the daemon going, but when we’re done, nothing will be listening on port 25, smtp.

So what we are setting up is called a ‘null client’. You just have to modify /etc/postfix/main.cf and master/cf according to the instructions at http://www.postfix.org/faq.html#null_client.

The main thing that was unclear to me is what line(s) constitute a ‘SMTP server entry’ in master.cf. After commenting out the line close to the top with ’service’ as ’smtp’ and ‘type’ as ‘inet’, I figured this was enough, as ’sudo lsof -i’ indicated nothing was listening on port 25, or as smtp. I would leave the other smtp service entries alone, the ones with ‘type’ as ‘unix’.

Then do ’sudo postfix reload’ and for good measure we may as well do ’sudo /etc/init.d/postfix restart’, or the equivalent on your linux distro.




When doing a push to master I was getting

bash: git-upload-pack: command not found
bash: git-receive-pack: command not found

The skinny: The path on your remote machine is not correct, at least the path being used for non-interactive shell logins. Most likely, updating the .bashrc of the remote user, (the user in the command) will fix your problem. Note that nothing on the client side of things really matters except that you have git-core installed and you may save a path to git-upload-pack in your local git settings if you wanted to.

Hoo boy, I have updated this after a not-so-fun experience with bluehost, ssh, bash, and git. After getting my ass kicked for two hours, turns out that my hosting issued some ssh updates that made it so no .bashrc or .bash_profile settings were being used for setting the path on shell logins and commands. Very nice.

Fix your path

Key 1: Figure out where the binaries for git are on the remote system. On my lame-o shared server they were in /home/<myusername>/local/bin. The folder will have a bunch of programs, or at least git, gitk, git-shell, git-upload-pack, etc.
Key 2: Make sure the path for your non-interactive shell login contains the folder where your git binaries are located. This following command, from the stackoverflow post, is awesome for seeing the ‘non-interactive shell’ path. Matt Curtis is great.

ssh you@remotemachine echo \$PATH

So if the result of ssh you@remotemachine echo \$PATH does not contain the folder where your git binaries are located, this is the source of the problem.

On the remote machine, login to the user being used for the git command, and make sure the .bashrc file sets the path correctly. You may not even need to add anything, but if you are reading this post chances are you need to include

export PATH=$PATH:/<pathtoyourgitbinaries>

in your .bashrc.

For all of us who didn’t immediately grasp what a ‘non-interactive shell login’ is, it goes as follows. When you login to a linux machine over ssh or at a desktop, this is an ‘interactive’ shell session, and loads the settings for the shell from .bash_profile in the home folder of the user who us logged in.

If you are simply issuing commands without logging in (like git clone, ssh somecommand, etc., or I guess just opening a bunch of shells in an os) then you are using a ‘non-interactive’ shell session. This will load settings from the .bashrc in the home folder of the user who us logged in.

A lot of times systems will have the .bash_profile call the .bashrc, so most relevant settings can go in the .bashrc.

But the difference in interactivity is why logging into an ssh session and doing echo $PATH will display a different path then issuing a non-interactive command like ssh you@remotemachine echo \$PATH.

Alternately, explicitly state the path to the git-upload-pack binary

If you can’t get the path settings in your (remote) .bashrc to work, you can tell git exactly where to look for the git-upload-pack binary. So bluehost users, or anyone else who has no control over the path setting for shells, you can explicitly use the –upload-pack option to explicitly set the path to the git-upload-pack binary you want. Example (Note that the upload-pack is an option with 2 hyphens -andanother- ):

git clone –upload-pack /home/<username>/bin/git-upload-pack <username>@<yourdomain>:/home/<username>/gitprojects/agitproject.git

If you have a git user for bare remote repos it will probably look like:

git clone –upload-pack /<somepathtoyourgitbinaries>/git-upload-pack git@<yourdomain>:agitproject.git

You can also add the server paths to your local git config

receivepack = /home/<myusername>/local/bin/git-receive-pack
uploadpack = /home/<myusername>/local/bin/git-upload-pack

where the config file is in the .git directory of my project on local. This line is under the entry for the remote I had set up called ‘origin’ (use the path on the server where the git install is located and make sure git-receive-pack is in there on the server).

Bluehost users getting the git-upload-pack: command not found error, or similar command not found errors can see the explanation of why you can’t control your .bashrc at http://66.147.243.109/index.php/kb/article/000572

See http://stackoverflow.com/questions/225291/git-upload-pack-command-not-found-how-to-fix-this-correctly

make[2]: execvp: Permission denied


Posted on August - 30 - 2009



make[2]: execvp: true: Permission denied

You need to do chmod 755 true on the true script on your bin, For me I had followed the instructions at:

http://blogs.koolwal.net/2009/07/20/howto-installing-git-on-bluehost-domain-hosted-websites/

for installing git on bluehost. I had to make a script called ‘true’, and put it in my local bin to get git to compile.

make[2]: execvp: <YOUR FILE HERE>: Permission denied

These errors mean that your script does not have execute rights. You can ‘chmod 755 <YOUR FILE>’ and it should work.