The Electric Toolbox Blog

Linux, Apache, Nginx, MySQL, Javascript and PHP articles

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.

Using the "ls" command to list directory contents from the command line with the -l flag will include the date and time down to the minute, but not show the seconds. This post shows how to display the seconds as well with bash on Linux and OSX.

On Linux

Use one of the following, the second one effectively being a shorter version / synonym of the first one:

Versions used

Top is a useful command line tool for showing processes running on Linux (and other operating systems) such as how much CPU and memory they've been using and how long they've been running, and also showing the system load, CPU and memory usage as a whole. But what if you only one to show output for one process or command?

Use the -p flag to specify the pid

If you know the pid number of the process, use the -p flag to specify it:

top -p [pid]

e.g.

top -p 1234

Combine with pidof if you don't know the pid

pidof will return the PIDs for the process that matches the input, so you can do this:

top -p `pidof [process name]`

The only problem with this is that if there's more than one process matching the name then it won't work, because you either have to specify each pid with another -p flag or comma separate the values, and you'll get an error like this, when trying to do top for just nginx:

which isn't ideal, because you're only get one of them, or combine it with some sed magic to convert spaces between the ids returned from pidof with commas:

top -p `pidof [process name] | sed 's/ /,/g'`

Replace [process name] with the process, e.g. with nginx as shown in the next example:

top -p `pidof nginx | sed 's/ /,/g'`

Combine with pgrep to match a name

Another alternative to combining top with pidof is to use pgrep. This can be useful if you need to match e.g. a PHP script which is running from the command line and which you could only match 'php' when running pidof and might return something different from what you want.

(Note that there is a -x flag for pidof which the man page says "Scripts too - this causes the program to also return process id's of shells running the named scripts" but it didn't seem to work when I tried it myself.)

If the script is called e.g. "myscript.php" you can do this:

top -p `pgrep -f myscript.php`

Again this will cause an error if it returns more than one pid. The output from pgrep will be have each pid on a new line, so we need to use tr to replace the newlines with commas and then sed to remove the final comma. If anyone has a tidier way of doing this, then please let me know in the comments.

top -p `pgrep -f myscript.php | tr '\n' , | sed s/,$//`

top -p `pgrep -f nginx | tr '\n' , | sed s/,$//`

And because pgrep does regular expression pattern matching, you can do all sorts of things with it, but note that there's a limit of 20 pids.

I'm sure you've done it before: added a commit message with git but typed it in wrong and need to change it. If you haven't pushed the commit yet then it's as simple as 'git commit --amend -m "New commit message"'.

Quick answer

If you haven't yet pushed the commit, use this to edit it in a text editor:

git commit --amend

Use this to do the whole thing from the command line:

git commit --amend -m "New commit message"

The full answer / more answers

I need a quick reference link to a comprehensive answer myself, hence this quick post. Several useful answers and examples covering a variety of situations is here at Stack Overflow.

Sendy is a self-hosted email marketing tool; while hooking up a subscription form, I needed to work out what all the possible responses are to a user subscribing, depending on their current status in the Sendy database.

Version

The version documented here is 2.0.7. The previous version had a bug in it which prevented the 'Already subscribed.' status from being returned as plain text and it would always return a full HTML page. If you are using an older version, you should upgrade.

Example API call using PHP

The following example calls the subscribe API function. Replace /path/to/sendy with the full domain and path to your Sendy install, and obviously the other fields too. The 'boolean' value in the data array is set to a text value of 'true' to return the response as plain text.

Where did it go?

From the horse's mouth

It notes that "Save for Web will not be removed without replacing its capabilities in a new and improved workflow."

I'm not much of a menu user, and use the somewhat awkward Cmd+Option+Shift+C keyboard shortcut so had never even noticed the change. My wife, on the other hand, uses menus and not keyboard shortcuts, and that extra step through the menu makes the current workflow much more awkward.

Solution 1: use shortcut keys

The first solution to speed things up is to use the shortcut keys. Cmd+Option+Shift+C is the default, but you can always change the shortcuts under Edit -> Keyboard Shortcuts. My own personal preference is to try to avoid changing shortcut keys so that I get used to them in case I need to use someone else's computer for something.

Solution 2: install the "Export Helper" add on

Yep, save yourself navigating through the menus / using an awkward keyboard shortcut by installing an add on... mind you, once you have the panel activated you now have one-click saving.

You need to have Creative Cloud file sync on, and it will automatically download it. Restart Photoshop and it will be under Window -> Extensions. When you click it, the panel will appear, but you'll probably need to drag it onto another group of panels otherwise I found it tended to disappear or be hidden or something.

To make sure Creative Cloud's file sync is on, go to Creative Cloud, click the cog, select "Preferences", then "Creative Cloud" then "Files" and the sync function is there. The screenshots below illustrate how to get there on a Mac; sorry, I can't help with Windows.

Viewing the email body with exim

I needed a really cheap standalone virtual server to test some stuff, on the internet and not running behind a VDSL router at my office, and got the cheapest RamNode server for $13.50 for a whole year.

RamNode servers

I honestly have no idea if RamNode are any good or not (my own websites are hosted using VPS servers at Linode), but for what I need this is perfect: it's more or less throw away money, and I get a server with a static IP address I can switch on, test some stuff and switch back off again as and when needed.

What am I testing?

I'm testing out the free Let's Encrypt secure certificates. These are domain validated certificates: validation is done by a certificate management agent on the web server, which receives requests from the LE servers to prove you manage the domain. I'll talk more about this in a future post, but suffice to say for the moment that I didn't want to run this on a production server (yet).

Get it here

Their cheapest one has 128MB of RAM, 12GB of storage and 500GB of bandwidth, running OpenVZ - for $15 for a year. You can get a 10% discount using the SSD10 coupon code. You can order it here and/or check out the other plans.

I am not affiliated with RamNode in any way, and the above link is not an affiliate link. I found out about them from the comments in this article at Ars Technica.

I have some automated processes that receive updates via email attachments which are base64 encoded. The entire email is backed up into a text file, and very occasionally I need to check what was in an attachment. The command line base64 tool can help with this, either decoding a file or standard input.

Using base64 to decode a file

The -d or --decode flag tells base64 it's decoding data (on a Mac -d is a debugging flag, so it's -D and --decode instead). In the examples below, I've used --decode, but you can use -d or -D instead.

To decode the file at /tmp/encoded.txt do this:

base64 --decode /tmp/encoded.txt

And the decoded file will be written to standard output. If you wanted to write it to a file, you can redirect it like this, where it's written out to /tmp/decoded.txt

base64 --decode /tmp/encoded.txt > /tmp/decoded.txt

Using base64 to decode some text

If you run base64 --decode without a file, you can type text (or copy and paste it), hit return/enter, and then control+d / ctrl+d and it will be decoded.

So, for example, to decode VGhpcyBpcyBiYXNlNjQgZW5jb2RlZAo=, which is "This is base64 encoded" encoded as base64, do this:

base64 --decode
VGhpcyBpcyBiYXNlNjQgZW5jb2RlZAo=
[ctrl+d]

It will then be written to standard output. Again, you can redirect the output to a file:

Using pbpaste on a Mac

If you have the encoded text in your clipboard, you can use pbpaste to pipe it through base64 instead of having to manually paste in the terminal. There are equivalent commands when using X (xclip) but I've never used these myself.

If it was nice and intuitive to install Java on Debian (and other Debian based distros such as Ubuntu), I wouldn't need to write this post because it would just be "apt-get install java". But no, I always forget what I need to install, hence this post...

Install openjdk-7-jre or openjdk-7-jre-headless

If you just want to install the runtime so you can run Java applications, install either openjdk-7-jre or openjdk-7-jre-headless. The first one will install a bunch of Gnome stuff if not already installed, so if you are doing this on a server without a GUI then install openjdk-7-jre-headless.