Chris Hope's LAMP Blog - The Electric ToolboxChris Hope's LAMP Blog - The Electric Toolbox

Linux Apache MySQL and PHP articles by Chris Hope

This is Chris Hope's blog for Linux, Apache, MySQL and PHP (known as LAMP) and Javascript/jQuery. I started this website several years ago with articles about web programming, Linux and Windows tips and tricks, howtos etc.

The ten most recent articles can be found below in their entirety. Navigating the sections in the right navigation (under Categories) will bring up all the other posts, and you can also use the search box at the top of the page to find what you might be looking for.

Delete messages from the exim mail queueDelete messages from the exim mail queue

Posted November 12th, 2014 in Email Servers

This post shows how to delete a single message from the exim mail queue and also how to remove all of them using the exim command line tools.

Delete a single message from the exim mail queue

Use mailq / exim -bp to show the mail queue, e.g.:

$ mailq
 0m   528 1XoIxD-0001rc-8J 

And then run exim -Mrm [message id] to delete the specific message:

exim -Mrm 1XoIxD-0001rc-8J

If the message is successfully deleted, you'll see this:

Message 1XoIxD-0001rc-8J has been removed

If exim is currently processing the message, you'll see this and it won't be deleted:

Message 1XoIxD-0001rc-8J is locked

You either need to wait and try again later, or get the id of the process which is currently processing the message, kill it, and then run the command again (e.g. "ps ax 1XoIxD-0001rc-8J" and then "kill -9 [process id/s]). It's probably not recommended that you kill the process.

Delete all messages in the exim mail queue

Running "exiqgrep -i" returns all the message ids for queued emails; pipe that through "exim -Mrm" and all the messages will be deleted, with the same caveat as above: if exim is currently processing a message, that one will not be deleted so you need to try again later.

exiqgrep -i | xargs exim -Mrm

And the result, if one could be removed and another one couldn't:

Message 1XoJ1U-0001sC-ME has been removed
Message 1XoJ1i-0001sQ-UJ is locked

Change the hide extension flag from the command line on OS XChange the hide extension flag from the command line on OS X

Posted November 3rd, 2014 in OSX

There doesn't appear to be an easy way to change the "Hide extension" flag on multiple files on OS X - selecting "Get Info" on multiple files simply opens a window for every file selected... If you have XCode installed, it can easily be done from the command line with setfile.

Hide file extensions with setfile

Run this command to hide the file extensions for e.g. all PDF files in the current directory using Terminal:

setfile -a E *.pdf

Show file extensions with setfile

And this command shows the file extensions for PDF files:

setfile -a e *.pdf 

Another way?

Let me know in the comments section below if there's another / better way of doing this. The chflags command comes installed with OS X, but doesn't appear to have the ability to change the file extensions setting.

Use exim and exiqsumm to show mail queued by domainUse exim and exiqsumm to show mail queued by domain

Posted October 31st, 2014 in Email Servers

There are a number of exim commands to see what's in the mail queue etc; sometimes you need to be able to see what's in the queue by domain, to see where hold ups might be.

exim & exiqsumm

This command gets what's currently in the mail queue and then pipes it through exiqsumm to collate the data into a useful format, instead of outputting every single queued message:

exim -bp | exiqsumm

Either run it as root or using sudo. You may need to pass the full path to the exim and/or exiqsumm commands (e.g. sudo exim -bp | /usr/sbin/exiqsumm).


By domain, the output shows the number of messages, the total kb/mb of mail queued and the oldest and newest messages queued:

Count  Volume  Oldest  Newest  Domain
-----  ------  ------  ------  ------
   11   495KB     14h     14h
   20   900KB     14h     14h
  154  6930KB     14h     14h

If you are using exim for sending bulk email (email marketing), using this command can help to show if you have any issues sending to particular mail services/servers (e.g. Gmail, Yahoo, Hotmail, etc). Then use the logs / other exim output to work out what the issue is to help fix it.

Promo codes, discount vouchers, etcPromo codes, discount vouchers, etc

Posted October 29th, 2014 in Miscellaneous Postings (Updated December 2nd, 2014)

This post has promo codes and discount voucher codes that I come across that I find useful and may need in the near future.

Use the promo code CYBERGOOD at checkout for $8.99 .COM and .NET registrations and renewals, as well as 50% off a bunch of products. They'll be donating to Colorado Feeding Kids with every .COM and .NET registration. This is valid until December 5th 2014 at - the normal price is $10.99

From December 6th to 31st, you can still get a minimal discount, using JAZZERCISE to get .COM & .NET registrations and renewals for $10.25.

Convert StudlyCaps to words with PHPConvert StudlyCaps to words with PHP

Posted October 23rd, 2014 in PHP

I needed to convert a bunch of database fieldnames in PHP from StudlyCaps to regular words, preserving the capitalization of words (e.g. from StudlyCaps to Studly Caps), and found a useful function on StackOverflow.

The solution

I'm almost certainly going to need this function again in the future, hence posting it here on my blog as a bookmark. The solution, posted here at StackOverflow, looks like this:

function StudlyCapsToWords($StudlyCaps) {
    return implode(' ', preg_split('/(?<=[a-z])(?=[A-Z])|(?=[A-Z][a-z])/', $StudlyCaps, -1, PREG_SPLIT_NO_EMPTY));

Note that I've put the code into a function and changed the variable name from the original example.

This works even better than what I was after, because it preserves capitals that follow one another as a word, but then splits it on the next capital. Make sure you go to the StackOverflow page for a full description of how it works.

Some examples

echo StudlyCapsToWords('DatabaseFieldName');
echo StudlyCapsToWords('ThisIsATest');
echo StudlyCapsToWords('TextWithCAPSInIt');

The above examples output:
- Database Field Name
- This Is A Test
- Text With CAPS In It

Copy OS X Yosemite installer to prevent multiple downloadsCopy OS X Yosemite installer to prevent multiple downloads

Posted October 17th, 2014 in OSX

Apple's OS X Yosemite upgrade is available today from the App Store for free, and weighs in at about 5.1GB. After downloading it via the App Store it's possible to make a copy of the installer so you don't need to download it again for each Mac you want to run it on.

Note, do this before installing the update

After downloading the update, the App Store saves the installer to the Applications directory and starts it, as shown in the screenshot below.

Do not click "Continue" until you have copied the installer. The reason? It gets deleted after the update has finished running.

os x yosemite installer

How to copy the installer

When the screen above appears, go and find the installer and copy it before clicking "Continue".

You can navigate to the installer in Finder from the menu selecting "Go" then "Applications" or by using the Cmd+Shift+A Finder shortcut keyboard combo.

Scroll down until you find "Install OS X Yosemite" and then copy it to some other location, such as a USB stick or external hard drive.

Now go back to the installer and click the continue button.

Run the installer on a second, third, fourth, etc... machine

You can now use the same application to install Mac OS X Yosemite on another machine. This afternoon I installed it onto my MacBookPro via the App Store, copied it to an external hard drive and then installed onto my MacMini from the external hard drive.

Is this legal?

Aside from the fact the upgrade is free, a single copy of Yosemite can be installed on each Apple-branded computer that you own or control. So yes, it's legal.

Why bother?

If you have super fast bandwidth and/or low or no data caps then maybe you don't want to bother going to the fuss of copying the installer, but if your bandwidth isn't so fast or you have a low data cap and/or bandwidth is expensive, then you might want to avoid having to download this 5.1GB update more than once.

MySQL queries to get the local part and domain from an email addressMySQL queries to get the local part and domain from an email address

Posted October 16th, 2014 in MySql

This post shows how to extract the local part and domain name from an email address using MySQL. The local part is the part before the @, for example "chris" in

Get the local part of the email address

Let's assume the email address column is called "email" and is in the "users" table, and that all email addresses in the database are valid with an @ in them.

SELECT SUBSTRING(email, 1, LOCATE('@', email) - 1) AS localpart FROM users;

This gets the first part of the email address up to the @ symbol, so the resulting data for "" would look like this:

| localpart   |
| chris       |
1 row in set (0.00 sec)

Get the domain part of the email address

SELECT SUBSTRING(email, LOCATE('@', email) + 1) AS domain FROM users;

This gets everything after the @ symbol, so the resulting data for "" would look like this:

| domain      |
| |
1 row in set (0.00 sec)

Getting both at the same time

There's no reason why you shouldn't put both into the same query:

SELECT SUBSTRING(email, 1, LOCATE('@', email) - 1) AS localpart,
       SUBSTRING(email, LOCATE('@', email) + 1) AS domain
FROM   users

And the resulting data:

| localpart | domain      |
| chris     | |
1 row in set (0.00 sec)

Debian releases and namesDebian releases and names

Posted October 13th, 2014 in Linux/Unix/BSD (Updated October 14th, 2014)

Debian releases are named after characters from Toy Story and are frequently referred to with the name rather than the version. This post is for my own quick reference for the version-to-name of each Debian release.

Debian version names

I've added the Toy Story character name into each row as well, because sometimes they're not completely obvious. For example, even though I've seen all the movies, it took looking up the name behind "Squeeze" to know it was the alien toys who first appeared in Toy Story 2.

Version Code name Release date Toy Story character
1.1 Buzz 1996-06-17 Buzz Lightyear
1.2 Rex 1996-12-12 Rex (the T-Rex)
1.3 Bo 1997-06-05 Bo Peep
2.0 Hamm 1998-07-24 Hamm (the pig)
2.1 Slink 1999-03-09 Slinky Dog
2.2 Potato 2000-08-15 Mr Potato Head
3.0 Woody 2002-07-19 Woody the cowboy
3.1 Sarge 2005-06-06 Sarge from the Bucket O' Soldiers
4.0 Etch 2007-04-08 Etch, the Etch-A-Sketch
5.0 Lenny 2009-02-14 Lenny, the binoculars
6.0 Squeeze 2011-02-06 Squeeze toy aliens
7 Wheezy 2013-05-04 Wheezy the penguin
8 Jessie not yet released Jessie the cowgirl
  Sid "unstable" The next door neighbour

Debian always has at least three releases in active maintenance: stable (currently Wheezy), testing (currently Jessie) and unstable, which is permanently named Sid after the boy next door in Toy Story 1 who liked to destroy toys.

Updating bash for shellshock on Debian 5 LennyUpdating bash for shellshock on Debian 5 Lenny

Posted September 30th, 2014 in Linux/Unix/BSD

If you are running Debian 5 Lenny and upgrading the distro to Debian 6 or 7 is not an option, you will need to compile bash from source, applying patches in order to secure your server against the bash shellshock vulnerability.

Patching bash on Debian 5 Lenny

Follow the instructions on this page under the "Patching older and unsupported systems" section. The page is kept up to date as new vulnerabilities are found, and shows the tests you need to run.

You will need to continue to monitor the page and apply updates as and when they become available by manually patching and compiling from source each time.

Note that the compiler may stall on "checking for working mktime..." for some time, but it will continue and finish compiling eventually.

An alternative option is to remove bash from your install and use another shell instead, obviously first making sure any shell scripts you have running will continue to function.

Warning: Skipping the data of table mysql.eventWarning: Skipping the data of table mysql.event

Posted September 29th, 2014 in MySql (Updated September 30th, 2014)

The events table was introduced to MySQL in 5.1.6 and when upgrading you will start to see the warning "Warning: Skipping the data of table mysql.event" when using mysqldump. This is not an error as such, but more to make it clear to you that something has changed.

How to include the event table with mysqldump

Use the --events flag when using mysqldump to include the events table:

mysqldump -u[username] -p --events mysql > mysql.sql

This will then suppress the warning message from the output.

How to exclude the event table with mysqldump

Use the --ignore-table flag when using mysqldump to exclude the events table like so:

mysqldump -u[username] -p --ignore-table=mysql.event mysql > mysql.sql

This will then suppress the warning message from the output.

Output when using -T / --tab flag

This is an update the day after originally writing this post. Using the above flags suppresses output when doing a straight SQL dump to file. When using the -T / --tab flag to write the data out to tabbed data files, you will still get this output when dumping events:

-- Dumping events for database 'mysql'

and this when attempting to ignore the table (which is the original message addressed by this post):

-- Warning: Skipping the data of table mysql.event. Specify the --events option explicitly.

This happens for me on two different servers which run MySQL 5.1.73. If anyone has any suggestions about how to suppress this output, while allowing other errors/warnings to be displayed, it would be greatly appreciated to prevent output from being emailed from automated backup processes.