Fixing Locale issues on Debian

Business as usual. New feature developed, tested, packed and ready to go. Let me just deploy it to production, smoke test aaaand …. damn! What happened to the currency symbols!?

In my particular case, PHP’s setlocale() returned false – so obviously those darned locales stroke again. SearchEngineOfYourChoice(TM) to the rescue!

Luckily even I was ably to fix this problem quickly without needing to contact the Admins (who wouldn’t have been in the office anyway):

$ locale -a
C
C.UTF-8
en_US.utf8
POSIX

Aha! It was missing almost all locales. However adding them is quite easy:

$ sudo dpkg-reconfigure locales

Generating locales (this might take a while)...
de_DE.ISO-8859-1... done
de_DE.UTF-8... done
de_DE.ISO-8859-15@euro... done
en_US.UTF-8... done
fr_FR.ISO-8859-1... done
fr_FR.UTF-8... done
Generation complete.

The dialog that appears after running this command shouldn’t be a problem at all, so I don’t mention it further here. Just select the locales you need there and go for it.

Afterwards check the results by again doing

$ locale -a

C
C.UTF-8
de_DE
de_DE@euro
de_DE.iso88591
de_DE.iso885915@euro
de_DE.utf8
deutsch
en_US.utf8
fran├žais
french
fr_FR
fr_FR.iso88591
fr_FR.utf8
german
POSIX

That’s already it. Don’t forget to restart your webserver!

Debug shell scripts (well, kind of)

I have to look up this one frequently, because it is really helpful.

If you want to see what lines of a shell script are actually executed, place this line in your code:

set -x 

I usually do that after the funny thing called Shebang (#!/bin/bash – I can also never remember this one correctly), but surely you can place it right before the section where you expect the problem. If you have an idea where the problem might be, that is. If not, just start from the beginning.

Cool thing: the variables are replaced in the output, or as the man page puts it:

Print a trace of simple commands and their arguments after they are expanded and before they are executed

Trap events

If you have cronjobs running to trigger a queue, you probably would like to take care that queue is not triggered multiple times, e.g. when the previous run is not finished yet. This can easily be done using a lock file which is written upon the next queue run and removed when it is done. So far, so good.

But what happens if the server crashed, or some Admins are restarting the VMs once a week to “solve strange problems”? Then you have to take care that the lock file is removed, otherwise your queue might not run again upon restart.

On Linux, this is very easy due to the handy “trap” command:

trap 'rm -f "my_lock_file.lock" >/dev/null 2>&1' EXIT HUP KILL INT QUIT TERM

The rm command that removes the log file is executed when either the EXIT, HUP, KILL, INT, QUIT or TERM signal is send. Now we don’t have to delete the file manually after a shutdown.

Pitfall: php_admin_flag vs. php_flag

Today I was almost going crazy about the PHP ini setting “display_errors”, which just couldn’t be convinced to be “On”. After some searching on the Internet without a result (“Must be an undiscovered bug … dammit”) I was about to give up. Hey, what do we have an error log for? But then good-old intuition stroke again – how about the vhost configuration?

Bingo:

php_admin_flag display_errors off

Who the f…? Well, me of course! I copied a bunch of these statements when taking another vhost configuration file as template, without having a closer look.

“php_admin_flag” is surely nice for hosters etc., because it sets the PHP ini value once and for all. That’s probably tricky, because ini_set() will simply return false, with no more information.

Note to myself: if setting ini values via vhost is really needed, better use “php_flag” instead. This way the value can still be overwritten.

Helpful MySQL shell tricks

Although I’m Windows user most of the time, I have to take care of some projects on Linux boxes, so it’s good to have at least a little knowledge of what you’re doing there.

The pipe really is a helpful little tool, which allows to do a mysqldump and directly gzip the result:

mysqldump my_database | gzip > my_dump.sql.gz

This surely saves some time during late night deploys!

You can even do a mysqldump from one server to another:

mysqldump my_database | ssh user@12.34.567.89 "cat >> /tmp/my_dump.sql"