Web, server, command-line and more: solutions log

Dave Everitt 23 Jun 2013, last updated (none)

Anyone who has to solve problems regularly is advised to keep a solutions log, so they never have to think ‘how did I do that last time?’ I haven't yet put up mine in a searchable or indexed way, so here's a massive long page.

Set up Apache2 for local website testing on Mac OS X 10.5

Relevant files:

in /etc/hosts add a line for each test site: mytestsite.lc myothersite.lc

in /etc/apache2/httpd.conf Uncomment the include to httpd-vhosts.conf
# Virtual hosts
Include /private/etc/apache2/extra/httpd-vhosts.conf

…and make local Apache only look for local files - change:
Listen 80

in /private/etc/apache2/extra/httpd-vhosts.conf
NameVirtualHost *:80

Add a VirtualHost block (more than one or just one?) e.g.:

    DocumentRoot "/Users/deveritt/Sites/mytestsite.com/webapps/html"
    ServerName mytestsite.lc

create a file e.g. /etc/apache2/users/mytestsite.conf by copying yourusername.conf and add directory blocks such as:

<Directory "/Users/deveritt/Sites/mytestsite.com/webapps/html">
    Options Indexes Includes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
    XBitHack on

Links and resources:

namevirtualhost (local copy)


Apache2, OSX 10.5, Leopard, virtualhosts, development environment, localhost

Set up SSI (includes) for html files using the XBitHack

In a Directory block for e.g. mytestsite.conf in VirtualHosts (or .htaccess if no root access), add:

XBitHack on

Then make files that need include directives to be processed executable:

chmod +x myfile.html

Links and resources:

ssi (local copy)


Apache2, SSI, includes, server side includes, xbithack

Django can't find flatpages/default.html, even though it's in a TEMPLATE_DIRS path

Wherever the templates directories are, there needs to be a directory inside it named the same as the project e.g.


Links and resources:


django, templates

ensure docutils is installed (use pip or easy_install) then add django.contrib.admindocs to INSTALLED_APPS.

Links and resources:


django templates, admindocs, docutils

Stop git tracking files that were deleted manually

Use git add -u.

git add .: looks at the working tree and adds all paths to staged changes if they are either changed or new (and not ignored). It does not stage any "rm" actions.

git add -u: looks at all currently tracked files and stages changes to them if different (or removed). It does not add new files, only changes to files already tracked.

git add -A: a handy shortcut for doing both the above.

Links and resources:

Stack Overflow: difference of git add a and git add,
what git gotchas have you been caught by,
difference between git add and git add u


git, deleted files

Use Django from trunk in your user directory instead of from Python's site-packages directory

E.g. ~yourusername/src/django-trunk, then you can update Django from trunk with svn update.

Links and resources:



django, svn, trunk

Install South from trunk when it's already there from easy_install

Delete the egg from Python's site-packages, and the relevant line in the easy-install.pth file.

$ svn co https://svn.aeracode.org/svn/south/trunk south
$ setup.py develop (to run in it's svn dir)

in .bash_login add the line:
export PYTHONPATH="/Users/MYUSER/src/south-trunk:$PYTHONPATH"

In the Python shell:

>>> import south
>>> south.__version__

Links and resources:

South docs installation archives


python, django, south, trunk

Find out what Python packages are installed and if there are newer versions

Install yolk (sudo easy_install yolk) and use the following to: list all packages; see if there are newer versions:

$ yolk -l
$ yolk -U

Links and resources:



python, easy_install, pip, yolk

Amend the descriptive message for the last git commit

git commit --amend -m "amended message here"

Links and resources:


git, message, commit, amend

Create and enable a new MySQL user

  1. Log into MySQL as root:
    $ mysql -h localhost -p -u root Enter password: (your password here)
    Switches used above: -h = host -p prompt for pw -u (name) MySQL username

  2. Set up new database (e.g. wedb) and assign to a MySQL user (e.g. webdev);
    if the user doesn't yet exist (or to change their password):
    mysql> grant all on wedb.* to webdev@localhost identified by "webdevpass";
    if the user does exist:
    mysql> grant all on wedb.* to webdev@localhost;
    In either case, you should see e.g.:
    Query OK, 0 rows affected (0.08 sec)
    then log out…
    mysql> quit;

  3. log in as the user (e.g. webdev):
    $ mysql -h localhost -p -u webdev
    Enter password: (your password here)
    mysql> create database wedb;
    you should see e.g.:
    Query OK, 1 rows affected (0.01 sec)
    then log out…
    mysql> quit;

  4. (optional) log into the new db:
    $ mysql -h localhost -p -u webdev webdb

Links and resources:

Paul DuBois, "MySQL and Perl for the Web", p13


mysql, database

Find what's on Python's system path

In the Python shell:

>>> import sys
>>> print sys.path

Links and resources:


python, python path

HTML in Javascript causes validation issues

For HTML: escape backslashes in closing tags for XHTML (although it's now dead):

<script type="text/javascript">
    ... unescaped script content ...

Links and resources:



Javascript, HTML, XHTML, validation, tags, entities, escaping, unescaped

Download/update and build NodeBox2 from trunk

cd ~/src (or wherever you keep your source files)
git clone git://github.com/nodebox/nodebox.git

To update:

cd ~/src/nodebox
git pull
sudo ant dist-mac

(see link 2 for "sudo" or not)

Open the dist folder under the NodeBox project folder, right-click the mac folder and select Compress. Rename the archive to also contain the version number, e.g. NodeBox-2.0.963.zip. Note that using the zip command from terminal creates an invalid executable.

Links and resources:



python, nodebox, nodebox2

Compile Java classes into a separate directory from their source files

cd to a dir where the ";src" and "bin" files reside.

$ javac -d bin src/dir1/dir2/source.java

The -d switch recreates the dir tree to "source.class" in the "bin" dir.

For classes that call others, "bin" should be in the CLASSPATH because classes are used during the actual compile as they"re created. Then you can jar up the classes, or recompile a new version. You can use -sourcepath and -classpath.

If there's a file that uses source.java in: src/dir1/dir3/another.java then this path is required too: src/dir1/dir3/ (separate multiple paths with a colon :).

If working with multiple projects or versions, keep paths away from CLASSPATH or the default Java class directory to avoid old/new class collisions, and consider using Ant or Maven which use XML to manage projects.

Links and resources:

Ant: http://ant.apache.org/
Maven: http://maven.apache.org/


java, CLASSPATH, compile

Enable HTML5 elements in IE<9 (and Firefox 2?)

Create a dummy element with Javascript and then just use it in your code - even IE6 will recognise it:

<!--[if lt IE 9]>  

Or use the HTML5 shiv in the head element:

<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>

Links and resources:

How to get html5 working in ie and firefox 2


HTML5, Javascript, IE, Internet Explorer

How to declare an HTML character set

Always specify a character encoding on every HTML document, either with the HTTP Content-Type header, the <meta http-equiv> declaration, or the shorter <meta charset> declaration.

Links and resources:



HTML, charset, UTF-8, character encoding

Find out is Apache is running as prefork or worker


apache2 -l

modules will be listed, and among them (if prefork):


or enter:

apache2 -V

which will show (e.g.):

Server version: Apache/2.2.9 (Debian)
Architecture:   32-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)

Also see my local document: apache-mod_wsgi-php-mod_python.txt.

Links and resources:

Apache multi-threaded vs multi-process pre-forked


apache, apache2, httpd, prefork, worker, multi-threaded

Add or remove a source to Ruby gems

gem sources -a http://gem_source_url

To remove a source:

gem sources -r http://gem_source_url

see current sources:

gem env

Note: gems.rubyforge.org, gems.github.com, and gemcutter.org have all been replaced by rubygems.org

Links and resources:

How to add source to ruby gems,
Good Ruby gem sources


Ruby gems, gem, sources

Use grep backrefs (in TextMate, etc.)

use numbered dollar signs $n e.g.

<h3 id="200$1">200$1

Example: regex for width or height attributes with no quotes:


Links and resources:


regex, textmate, grep, backrefs

Set up a new domain/subdomain on a Debian Linux server under Apache2

  1. General (domain):
    setup the domain in Fasthosts/Rimu DNS control panel BEFORE setting Rimu name servers at the domain name registrar:
    Rimuhosting (ecoconsulting.co.uk): https://rimuhosting.com/dns/records.jsp
    Fasthosts (subdomain): add new subdomain "A" record in "Advanced DNS" and point to the server IP address.

  2. adduser [newusername] (follow prompts to add password etc.)
    Add sub-directories: html, logs and cgi-bin as specified in the VirtualHost block (or Apache will choke).
    password_here - domain_url_here

  3. Create/copy a .conf a file in: /etc/apache2/sites-available/

  4. Enable the site:
    a2ensite sitename.conf for a list of available sites, just hit return after a2ensite.

  5. Restart apache
    apache2 -k graceful (Ubuntu) or (Debian)
    /etc/init.d/apache2 restart (reload will not do it)

  6. add an index.html file under the html directory - this should appear but might need an hour or so for the DNS to propogate.

  7. chown and chgrp * everything (except the .. file, which will stay root anyway)

Links and resources:


apache, a2ensite, dns, adduser, domain, subdomain

enable an apache module

a2enmod include (e.g. turn on SSI) then:
/etc/init.d/apache2 restart

Links and resources:


apache module, a2enmod

Unix/Linux warns of stopped jobs on logging out

ps aux (list jobs)
ps (list jobs with id)
w (see what's going on)
%1 (1 = job number)

Or interrupt the foreground job before it completes:

Bring background job to foreground:

Stop job e.g. 1 with
kill %1

Links and resources:


unix, linux, ps, jobs, kill

Perl "Premature end of script headers"

One often-overlooked cause is the wrong Unix/Linux owner and group for the script file throwing the error.

Links and resources:

Common Web dev error messages and what they mean


perl, cgi, script error, premature end of script

Get basic WSGI working with Apache for testing

Get WSGI working with Apache to test things before doing any framework-specific setup (like Django)

General Apache & mod_wsgi instructions:

Do this NOT in the DocumentRoot directory, but in a place (in the user's directory) where Apache can be made to have read access to the wsgi file and the containing directory.

  1. create a (test) WSGI application script file e.g. "test.wsgi" and put this in it:

    def application(environ, startresponse): #function name: "application" status = "200 OK" output = "Hello WSGI!" responseheaders = [("Content-type", "text/plain"), ("Content-Length", str(len(output)))] startresponse(status, responseheaders) return [output]`

  2. (a) put your wsgi script in a directory other than your site's root directory, add the WSGIScriptAlias line to either your apache config file (httpd.conf) or your site's VirtualHost container (e.g. Debian/Ubuntu: /etc/apache2/sites-enabled/) and allow Apache to access it e.g. for mysite.com/test:

    ServerName blog.mysite.org ServerAdmin deveritt@innotts.co.uk

    DocumentRoot /home/deveritt/html Order allow,deny Allow from all

    WSGIScriptAlias /test /home/deveritt/test/test.wsgi Order allow,deny Allow from all

  3. (b) Or, to serve from the DocumentRoot directory for mysite.com or blog.mysite.com you need to make aliases for Apache (not the WSGI app) to serve static media:

    ServerName blog.mysite.org ServerAdmin deveritt@innotts.co.uk

    DocumentRoot /home/deveritt/html

    Alias /robots.txt /home/deveritt/html/robots.txt Alias /favicon.ico /home/deveritt/html/favicon.ico

    Alias /media/ /home/deveritt/html/media/

    Order allow,deny Allow from all

    WSGIScriptAlias / /home/deveritt/wsgi-scripts/test.wsgi

    Order allow,deny Allow from all

  4. Or (preferred) start as a daemon process (so you can reload your script with e.g. "touch myscript.wsgi")


  5. restart Apache and visit: mysite.com/test or (for the DocumentRoot setup) mysite.com

For django see Graham Dumpleton's guide (on ecoconsulting.co.uk?) "grahamd-django-modwsgi.txt"

Links and resources:

my post on modwsgi


wsgi, apache, mod_wsgi

Quickly create a file and add content from the command-line


touch filename.txt
echo "stuff to add" >> filename.txt

adds the line with a newline at end.

or create and add multiline text:

cat > filename.txt <<-"END"
stuff to add
another line and a final return

then add more with:

cat >> filename.txt <<-"END"

(then same as above)

or simpler:

cat > filename.txt
line 1
line 2
another line

when finished, hit return and ctrl-D.

then add more with:

cat >> filename.txt

(then same as above)

To prepend text, use sed and mv:

sed '1i\
type new text here then close single quote



Links and resources:

sed insert text top file


touch, append, prepend, sed, cat, files, file

use sed to replace text in multiple files

on OS X

sed -i '' 's/oldtext/newtext/' *.html

e.g. to replace old XHTML br tags with non self-closing ones in all files with an .html extension:

sed -i '' 's/<br\/>/<br>/' *.html

Note: escape forward slashes within your text strings: \/

Empty '' not needed on Centos (and possibly other Linux?)

or for recursive within dirs (omitting ” for non OS X):

find ./ -name "*.html" | xargs sed -i 's/<br \/>/<br>/' *html

Links and resources:

search and replace in all files within a directory recursively,
sed.sourceforge.net Common one-line sed scripts: : sed.sourceforge.net/sedfaq3 : quick note about seds edit in place option : grymoire.com/Unix/Sed : zytrax.com/tech/web/regex.htm#sed : search and replace recursively using sed and grep


sed, search, replace, files, file

Find all files modified after a certain number of days

find . -mtime -60 -ls

where "60" is the number of days.

Links and resources:


find, files, modified, date, mtime

Test Apache and get stats readout

Use the Apache HTTP server benchmarking tool ab:

ab -c 10 -n 20 http://mydomain.org/

gives requests per second, etc., and:

/usr/sbin/httpd -V

gives version and compilation flags.

Links and resources:

man ab


apache, http, benchmark, server

The code snippets below are provided as examples, with CSS and Javascript comments.

The menu is an unordered list with a .menu class attribute, inside the usual “wrapper” div:

<div id="wrapper">
  <ul class="#menu">
    <li><a href="#">link one</a></li>
    <li><a href="#">link two</a></li>
    <li><a href="#">link three</a></li>

In this example there is a global link style of pale grey with a dark grey hover:

a:visited { color: #999; }
a:hover { color: #666; }

If JQuery is used to fade in the hover state colour at this stage, the first hover over a link will show the sudden css hover - the fade will only appear on the second hover.

So, to preserve this css hover rule without javascript, one solution is to create a css class that matches the css :hover colour attribute to the :link state, allowing the JQuery color fade to show first time. This is only appended to the "wrapper" div by JQuery if javascript is available:

/* if javascript is available the .js class is only added with JQuery, so
   css hover and link colours match and the JQuery fade shows instead */
.js .menu a:hover {
  color: #999;

Add the JQuery function just before the closing /body tag

$(function() {
  /* add .js class that matches css link and hover states */

  /* fade in the hover state colour (and fade it out again) */
  $("#menu li a").mouseenter(function() {
    $(this).animate({ color: "#333" }, 600);
  $("#menu li a").mouseleave(function() {
    $(this).animate({ color: "#999" }, 400);

Now, hovering over the links won't show an initial sudden css colour change (to #666) instead of a fade. Adding the .js class to the wrapper div means that this effect can also be applied to other links inside it - just add their selectors to the $("#menu li a") part like this: $("#menu li a, #submenu li a").

"View source" will not show the JQuery-generated class="js" addition to the "wrapper" id - you will need to inspect the generated source code (right-click > "inspect element" in Safari [other browsers?]).

Links and resources:

JQuery API .addClass() page (my post didn't appear),
JQuery mouseenter function


jquery, jqueryui, mouseenter, addclass, hover, css, color, colour

Return a value from a Perl subroutine: a 2-liner



if (spamcheck()) { print "Spam!" } else { print "In the clear!" }
sub spamcheck { return 1 if (2+2 != 4) }

Links and resources:


Perl, subroutine, return

Show Perl CGI errors in the browser

use CGI::Carp qw/fatalsToBrowser/;

Links and resources:



Perl, carp, errors, cgi, browser

CPAN basics and maintenance

From within the CPAN shell

save config: o conf commit


install CPAN
reload CPAN

help: h
quit: q

Links and resources:


Perl, CPAN

wget isn't installed by default on OS X

solution: use curl instead, or install wget. curl -O recreates remote dirs locally.

Links and resources:

OS X using curl instead of wget


unix, curl, wget, os x

Checking disc space (Linux/Unix) and memory use

disc space:

df -h

memory use (nice summary):

free -m

see memory use and swaps at 30-second intervals, and show inactive and active

memory (-a)
vmstat 30 -a

list users:

cat /etc/passwd

Links and resources:

Check free space,
man vmstat


memory, ram, swap, disc, disk, unix, linux

Managing Linux/Unix users (e.g. remove a user)

userdel -r USERNAME

Link also handy for user admin

Links and resources:



linux, unix, user, users, remove

Managing Java versions on OS X

java -version

Leopard 10.5 upgrades to Java 1.6 Check:
Utilities > Java > Java Preferences
drag 1.6 to the top and check the box, but also leave 1.5 checked.
If 1.6 isn't there, install "Java for Mac OS X 10.5 Update 7"

Remove (e.g.) Java 1.6

% rm ~/Library/Caches/Java/deployment.properties
% sudo rm -rf /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0
% sudo rm /System/Library/Frameworks/JavaVM.framework/Versions/1.6

That's it - you"ll have 1.5 as the default again. If you have a folder named "Java SE 6" in /Applications/Utilities/Java, delete that too.

Scott Kovatch, Apple Inc., Java Runtime Classes

Links and resources:

OS X Java versions: : developer.apple.com/library/mac/#technotes/tn2002/tn2110
: lists.apple.com/archives/java-dev/2007/Oct/msg00637

Java for Mac OS X 10.5 Update 7: : support.apple.com/kb/HT4140 : support.apple.com/kb/DL971

Important Java Directories in OS X


OS X, Java, Java 1.6

Get MySQL configuration data (port, etc.)

Open the MySQL shell: $mysql

See MySQL configuration data: mysql> show variables;

View general MySQL status: mysql> status;

Links and resources:



mysql, port, configuration

Simple Python list comprehension examples

>>> timesten=[1,2,3,4,5,6,7,8,9]
>>> print [v*10 for v in timesten if v>4]
[50, 60, 70, 80, 90]
>>> multi = dict([(v,v*10) for v in timesten])
>>> print multi
{1: 10, 2: 20, 3: 30, 4: 40, 5: 50, 6: 60, 7: 70, 8: 80, 9: 90}

Links and resources:

Programming Collective Intelligence: Building Smart Web 2.0 Applications


python, list comprehension, example

Why document.write isn't the best method

There are better ways to incorporate strings into HTML content, such as .innerHTML and .createElement or HTML cloning patterns - document.write should be avoided because:

  1. it is recklessly dependent on timing, so if called before the onload event, it appends or inserts text into the page. If it is called after onload, it completely replaces the page, destroying what came before.

  2. document.write encourages bad structure, in which script and markup are intermingled. A cleaner structure has minimal interaction between markup and script.

Links and resources:



javascript, document.write, html

Javacript HTML script tag blocks: uses, abuses and hints

  1. Don't add HTML comments <!-- //--> - these haven't been necessary for years. Also, technically the comment contains a javascript decrement: -- .

  2. Within Javascript, this: </ should always be escaped thus: <\/

  3. Put the src attribute first: script src="url"

  4. type="text/javascript" is optional - the browser knows what to do

  5. Add scripts as late as possible, just before the closing </body> tag is best, but ensure that they load before they"re called on the page.

Links and resources:



javascript, html, script tag, type attribute, script src attribute

Included files inside utf-8 parent file not showing non-ascii characters

After setting up a directory block in vhosts e.g.:

<Directory /home/adomain/html>
    Options Includes
    XBitHack on
    AddType text/html .inc

(NOTE: preceding + only needed if also a - setting e.g. -Indexes)

chmod only files to be parsed (i.e. containing SSI directives) to 744.

Make sure included files themselves are saved with utf-8 encoding from the text editor. Otherwise (even if the parent html page is utf-8) they"ll be imported with their file encoding, and won't even respond to Apache directives like AddDefaultCharset.

Links and resources:

Server side includes and character encoding


SSI, server side includes, includes, Apache, utf-8, encoding, charset

Avoid incompatible filename characters and insignificant files on servers

Windows file system incompatible characters

< (less than)
> (greater than)
: (colon)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)

Small operating-system-specific files that can be deleted safely from a server:

Links and resources:



file, filename, incompatible characters, file system, Windows, OS X, Linux, compatibility

Renumber ordered lists using CSS :before instead of deprecated "start" attribute

Various possibilities, including some styles for aligning :before-generated numbers:

The CSS:

/* the basics */

.numlist {
  counter-reset: item;
.numlist li {
  list-style-type: none; /*display: block; also removes numbers*/
.numlist li:before {
  content: counter(item) ". ";
  counter-increment: item;
.numlist2 {
  counter-reset: item 4;

/* variations with increment additions and alignment */

.numlist3 li:before,
.numlist4 li:before {
  counter-increment: item 4; /* count list numbers in fours */
.numlist3 li:before {
  float: left; /* or display: inline-block; to pad numbers*/
  width: 1.75em; /* width aligns list items after numbers */
.numlist4 li:before {
  float: left;
  text-align: right;
  padding-right: 0.5em; /* padding combined with... */
  width: 1.25em; /* ...width aligns list items */


<ol class="numlist">
  <li>group one</li>
  <li>group one</li>
  <li>group one</li>
  <li>group one</li>

Continues from the above with counter-reset: item 4:

<ol class="numlist numlist2">
  <li>group two</li>
  <li>group two</li>
  <li>group two</li>
  <li>group two</li>

Count in fours with counter-increment and align list items with a width value:

<ol class="numlist numlist3">
  <li>group three</li>
  <li>group three</li>
  <li>group three</li>
  <li>group three</li>

Align list items and right-align smaller to larger numbers with width, text-align and padding:

<ol class="numlist numlist4">
  <li>group three</li>
  <li>group three</li>
  <li>group three</li>
  <li>group three</li>

Links and resources:

Make ol list start from number different than 1 using css


html, css, ordered list, numbering, numbers, start attribute, counter-reset

PNG file with alpha transparency and opacity fades to black in Internet Explorer

Don't use an ie-specific opacity filter in css for elements having a background png image with alpha channel transparency. There is a fix (see link) using an IE filter and rgba, which can be activated using Javascript/JQuery or placed in a CSS file.

Links and resources:

PNG transparency problems in IE8


CSS, IE, Internet Explorer, png, alpha, transparency, opacity

Border-radius fails for images in Firefox

wrap the image in a span with the same height and width as the image, apply border-radius to the span and use the image as a background to the span. The xhtml-only SVG clipping path method works, but fails with box-shadow (adding the path the the outer border of the shadow), and isn't future-proof (i.e. FF 4 supports border-radius for images).

Links and resources:

Firefox img rounded corners SVG,
Adventures in web 3.0 part 2: css3


CSS3, border-radius, Firefox, image, img

For Joomla 1.6, find the template:

Use $this->item->parent to wrap the h2 tag in a link to the item's parent page:

  echo '<a href="' . JRoute::_(ContentHelperRoute::getArticleRoute($this->item->parent)) . '">';
  echo $this->escape($this->params->get('page_heading')) . '</a>';

Update: in a later version of Joomla 1.6 this gives an empty "?id=" suffix to the URL, so here's the solution for the actual URL part above:

str_replace("?id=", "", JRoute::_(ContentHelperRoute::getArticleRoute($this->parent)))

This question about mod_rewrite is related.

Links and resources:

Hiding the article id in a joomla menu


Joomla, PHP, this->item->parent, heading, h2

Obtain the digital root of any integer

dr = the integer rt = formula for obtaining the digital root of the integer


irb> dr = 298749875
=> 298749875
irb> rt = 1 + (dr - 1)%9
=> 5


>>> dr = 298749875
>>> rt = 1 + (dr -1 )%9
>>> rt

Perl one-liner in terminal:

perl -e '$dr = 298749875; $rt = 1 + ($dr - 1)%9; print "$rt\n"'

Links and resources:



number theory, maths, digital root, Ruby, Python, Perl

When to use Python xrange() over range()

xrange() is more efficient than range() especially for larger iterations: range creates a list, so if you do range(1, 10000000) it creates a list in memory with 10000000 elements, while xrange is a generator, so it evaluates lazily and keeps only one number in memory. When testing this I found the following:

import time

for x in range(1, 10):

    t = time.time()
    [v*10 for v in range(1, 10000)]
    print "range:  %.4f" % ((time.time()-t)*100)

    t = time.time()
    [v*10 for v in xrange(1, 10000)]
    print "xrange: %.4f" % ((time.time()-t)*100)

run it:

$python range_tests.py
range:  0.4273
xrange: 0.3733
range:  0.3881
xrange: 0.3507
range:  0.3712
xrange: 0.3565
range:  0.4031
xrange: 0.3558
range:  0.3714
xrange: 0.3520
range:  0.3834
xrange: 0.3546
range:  0.3717
xrange: 0.3511
range:  0.3745
xrange: 0.3523
range:  0.3858
xrange: 0.3997 <- garbage collection?

Or, using xrange in the for loop:

range:  0.4172
xrange: 0.3701
range:  0.3840
xrange: 0.3547
range:  0.3830
xrange: 0.3862 <- garbage collection?
range:  0.4019
xrange: 0.3532
range:  0.3738
xrange: 0.3726
range:  0.3762
xrange: 0.3533
range:  0.3710
xrange: 0.3509
range:  0.3738
xrange: 0.3512
range:  0.3703
xrange: 0.3509

Links and resources:

"Python in a Nutshell" ,
Difference between range and xrange,
Python Performance Tips


Python, range, xrange, iterator, timeit

A snippet to wrap an editable string around a selection in TextMate

Bundles > Show Bundle Editor
then choose "New Snippet" from the add + button (bottom left) and use:


where editme is the default editable value. If you add a new snippet shortcut in the "Key Equivalent" field (e.g. ctrl-shift-alt-W) you can then wrap any selection in an editable pair of words.

Note: once the shortcut is allocated, you can't edit a snippet in place - you need to start again (I think - couldn't find a way around that).

Links and resources:

TextMate editing 2 words at same time


TextMate, snippet, wrap

iTunes won't accept album artwork or wma files

Convert files to m4a (the free version of Switch works)

Links and resources:



iTunes, artwork, m4a, wma

Install MongoDB on OS X

The "quickstart" on the MongoDB site could be clearer. Here's a condensed version with more info.

  1. Get the URL (copy the URL, don't click) for the latest download for your system from: http://www.mongodb.org/downloads

  2. Open Terminal and go to where you keep source files (good to create a directory if you don't have it already) e.g.: cd ~/src then type curl, the URL you"ve copied, > (between spaces) and the filename you"ll save it as e.g. (for the 64-bit version of Mongo 1.8.1):
    curl http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-1.8.1.tgz > mongo.tgz

  3. Make the default directory for MongoDB to store it's data - type:
    mkdir -p /data/db
    (-p also creates the intermediate "data" directory)
    If you want see what's there after you"ve used MongoDB, type:
    cd /data/db;ls -al

  4. Add a couple of aliases to your .bash_profile, .bashrc, .bash_login (or wherever you keep your custom bash stuff) e.g. for the above version of MongoDB downloaded to ~/src:
    alias mongod="/Users/yourusername/src/mongodb-osx-x86_64-1.8.1/bin/mongod"
    alias mongo="/Users/yourusername/src/mongodb-osx-x86_64-1.8.1/bin/mongo"

  5. To use these new aliases, close the Terminal window and open a new one. You can now test MongoDB by starting the MongoDB server with:
    then open another Terminal window and type:
    In the MongoDB shell that's now started up, create and retrieve a test document "foo":
    > db.foo.save( { a : 1 } )
    > db.foo.find()

Links and resources:

Mongo OS X Quickstart,
Bashing up MongoDB on Mac OS X 10.6


MongoDB, OS X, bash, Terminal, Leopard, Snow Leopard

No root permission to install Perl modules

  1. cd to a directory where you have permissions and download the module e.g.:
    curl -O http://search.cpan.org/CPAN/authors/id/M/MJ/MJEVANS/DBD-ODBC-1.29.tar.gz

  2. Untar (the usual):
    tar xvfz DBD-ODBC-1.29.tar.gz

  3. use makefile with your directory:
    perl Makefile.PL PREFIX=/home/my_user_dir/my_perl_libs

  4. then make as normal. Then use lib "/home/my_user_dir/my_perl_libs" in your code before "use"ing ODBC

Links and resources:


perl, module, install, permissions

Installing Rack > 1.2.0 fails with Ruby 1.8.6

Downgrade to Rack 1.2.0:
sudo gem uninstall -v 1.2.2 rack

or, if you don't already have Rack 1.2.0:
sudo gem install -v 1.2.0 rack

The Github fix for Rack (see links) needs: bacon, memcache-client, thin and fcgi, but the latter won't install with gem, as it needs the fcgi lib, although apparently you can install fcgi-devel instead (e.g. Gentoo):
yum install fcgi-devel

Could install Ruby 1.8.7 but readline issues on Tiger (OS X 10.4) are a pain.

Links and resources:

Rack fix for Ruby 1.8.6,
How to set up Apache with FastCGI and Ruby bindings,
FastCGI gem installation not possible under Windows?,
Rails: can't install fcgi?,
Compiling Ruby 1.8.7 on a PowerBook G4 with Mac OS X 10.4


fcgi, Ruby, gem, fcgi-devel, Rack, install

Microsoft Word keeps reverting to US English/a default font/whatever

solution: Find and edit the basic template Normal.dotm, then save it. All new documents will reflect the changes. In OS X you"ll find it here:
[home]/Library/Application Support/Microsoft/Office/User Templates/Normal.dotm

Links and resources:


Word, template, default, Normal.dotm

Set logs to rotate in Apache

Find rotatelogs, then add the following (e.g. depending on your paths) to the VirtualHost block for that domain:

ErrorLog "|/usr/sbin/rotatelogs /home/USER_NAME/logs/error.log.%Y-%m-%d 5M"
CustomLog "|/usr/sbin/rotatelogs /home/USER_NAME/logs/access.log.%Y-%m-%d 5M" combined

Links and resources:


apache, logs, log, rotate, rotatelogs

A simple example to distinguish NoSQL from traditional relational databases

Summary with direct quotes from article (see refs):

NoSQL is a bit of a catch-all: there’s a big difference between key/value stores and document databases”

relational gives you solid transactions and joins, NoSQL is fast and scales. …a many-to-many relationship in a relational database might look like:

Posts(id, title, body)
PostTags(post_id, tag_id)
Tags(id, name)

relational databases are tuned to deal with this scenario using joins and foreign keys. In a document database, the typical way to represent this is:

    title: 'My Post',
    body: 'This post has a body',
    Tags: ['ruby', 'rails']

Notice the denormalization of tags so that there is no longer a table for it so to get a list of all tags using map/reduce:

    mapreduce: 'posts',
    map: function() { 
        for (index in this.tags) {
            emit(this.tags[index], 1);
    reduce: function(key, values) { return; },
    out: "tags"

This function can be run periodically to create a tags collection from the posts collection. It’s not quite real-time, but … close enough for most uses. (…for real-time, there are other techniques) …the query is more complicated than just selecting out of Tags, but inserting and updating an individual post (the main use case) is simpler.

Add the remaining, and last 3 links, to my NoSQL Google doc: if you don’t know how to use document database specific features such as map/reduce, or how to model your data … to take advantage of them, you won’t be able to adequately evaluate those databases. Similarly, if you don’t know how to use pessimistic locking or referential integrity in a relational database, you will not see how much time and effort it could be saving you over trying to implement such robustness in a NoSQL database that wasn’t designed for it.

“the most common interpretation of “NoSQL” is “non-relational”, although NoSQL is not meant as anti-RDBMS, but emphasizes the advantages of Key-Value Stores, Document Databases, and Graph Databases” “Typical RDBMS implementations are tuned either for small but frequent read/write transactions or for large batch transactions with rare write accesses. NoSQL on the other hand, services heavy read/write workloads” - WIkipedia

Links and resources:

Relational Or NoSQL With Rails? (Xavier Shay: "Robot Has No Heart"),
Wikipedia: NoSQL,
NoSQL doesn’t mean non-relational,
Carlo Strozzi's original NoSQL (1998)


database, NoSQL, MySQL, MongoDB, CouchDB, Redis, normalization

Find the version of your bash shell

$ which bash
$ /bin/bash --version
GNU bash, version 2.05b.0(1)-release (powerpc-apple-darwin8.0)
Copyright (C) 2002 Free Software Foundation, Inc.

(yeah, I know that's a really old version of bash I was running!)

Links and resources:

Bash: find out version


bash, shell, version

Make changes to currently running bash shell take effect

You"ve changed a variable in a bash configuration file (e.g. with: export VARNAME=the-new-value), and you want it to take effect without leaving the shell - enter:
source .bash_login (or .bash_profile, or whatever the name of the changed bash config file is)

Links and resources:




solution: Go to the dir where you want the link and type:

ln -s source_file link_name

substituting your details for the following values:

Links and resources:


linux, unix,symlink, symbolic link

Mongo "Unable to create / open lock file"

If you're running mongo under a user, and there's an error on running mongod like this:

"Unable to create / open lock file for lockfilepath:
/data/db/mongod.lock errno:13 Permission denied, terminating"

change the owner of mongo's data directory:

sudo chown `id -u` /data/db

Links and resources:

Stack Overflow: Why can't I start the mongodb


mongo, mongodb, permissions

Mongo 32-bit won't run on OS X 10.4.11 (Tiger)

Download and use this:

“We"ll end up having a separate build for tiger - so the 32-bit regular os x build isn't expected to work. We should be getting the tiger build up and running for people to test sometime today. Building from source should also work though.” - Michael Dirolf

Links and resources:



mongo, mongodb, tiger, OS X 10.4

Ruby on Rails fails with “Could not open library "libmagic.1.dylib"”

No need to install the whole of ImageMagick (with it's dependencies), you can install the missing library from:

The script from the link below (by Max Howell, author of Homebrew) can be adapted for use without Homebrew.

Links and resources:

libmagic.rb script by Max Howell (Homebrew)


imagemagick, ror, ruby on rails, libmagic

Ruby Version Manager (RVM) install problems on OS X 10.4 (Tiger)

there's a version of the install script for this OS on the Google Groups RVM list.

Links and resources:

Google Groups: OS X 10.4 RVM install script


Ruby Version Manager, rvm, tiger, OS X 10.4

Recipe: watercress and goats" cheese muffins (cow-dairy-free)

Ingredients (serves 10)

Links and resources:



recipes, muffins, scones, goat's cheese, goat's milk

Find the obscure privacy settings in LinkedIn

Links and resources:

A box you want to uncheck on linkedin,
LinkedIn privacy stuff up


privacy, linkedin, data sharing

easy_install numpy fails

easy_install pip
pip install numpy

Or use the Enthought Python package, which incldes NumPy, SciPy, etc.

Links and resources:



python, numpy, pip, scipy

Remove exsiting Python module install from site-packages

Before updating a Python module, you should remove the existing version.

For Debian:

OS X (e.g. Python 2.6)

remove module folder and egg. If listed in easy-install.pth, also remove relevant line.

Links and resources:


Python, site-packages

Apache2.2 command apachectl fails on OS X 10.5 or 10.6

Running apachectl (command) throws error:

/usr/sbin/apachectl: line 82: ulimit: open files: cannot modify limit: Invalid argument

Open /usr/sbin/apachectl and comment out line:

ULIMIT_MAX_FILES="ulimit -S -n `ulimit -S -n"

replace with:

ULIMIT_MAX_FILES="ulimit -S -n"

Links and resources:

Open files cannot modify limit invalid argument


apache2, os x, apachectl

Require a specific Ruby gem

Example for oci8

gem 'ruby-oci8', '=1.0.7'
require 'oci8'     # NOTE: file required (oci8.rb) not same
                   # name as gem, as is frequently the case

Links and resources:

Require a specific version of a Ruby gem


ruby, gem, require

Get Safari to show a new favicon

Safari tends to hang on to the version of a favicon loaded when a website is first visited. Go to ~/Library/Safari and move the file "WebpageIcons.db". Reload the page, then replace the file. If this doesn't work, you may need to go to History > Show All History and delete all pages showing the icon you want to replace, and try again.

Links and resources:


Safari, favicon

Calculate one number as a percentage of another

Excel: =((smallerNumber/largerNumber)%)*10000
e.g. for 7.84 as a % of 29.75 = 26.35 =((7.84/29.75)%)*10000

Calculator without % key:
20% of 190 = 38 190 * 0.2
7.84 as a % of 29.75 = 26.352 7.84 / 29.75 * 100

Links and resources:



percentage, percent, excel

Find location of a Python module

>>>import [module]

Links and resources:

Location of Python module sources


python, module

Git: remove a file after adding but before committing

git rm --cached [filename]

Links and resources:

Stack Overflow: undo git add before commit


git, remove

Convert Markdown to HTML using Kramdown:

E.g. enerate an HTML file "mywebfile.html" from a markdown file "mymdfile.md":

kramdown my_md_file.md | cat > my_web_file.html

Links and resources:


markdown, kramdown

Use RedirectMatch for changed file extensions

RedirectMatch takes an argument e.g. for a permanent redirect use 301:

RedirectMatch 301 (.*)\.htm$ http://myserver.com$1.html

Links and resources:

301 redirect


Apache, redirectmatch

Use mod_rewrite for a changed domain

R=301 marks the Redirect as permanent (301), L means make this the last rule:

RewriteEngine ON
RewriteRule ^(.*)$ http://mynewdomain.com/$1 [R=301,L]

Links and resources:



Apache, mod_rewrite

Add rar and unrar capability to OS X

Firstly, download RAR for OS X from RarSoft, double-click to archive and drag the resulting rar folder to Applications.

Leopard 10.5: go to your Home folder and open Library/Workflows/Applications/Finder.

Snow Leopard 10.6: go to Home/Library/Services.

Create any of these folders if they don't exist.

Download this Automator script and put it in the Finder folder above (the megaupload.com download is not available).

You can now right- or ctrl-click on a folder or file in the finder and (from the bottom of the resulting menu) choose More > Automator > RAR selected files. It's slower than creating a zip archive (so if it's a large file or folder, give it time), but it works.

To just unrar on OS X, use MacPAR, UnrarX or The Unarchiver.

Links and resources:

How to compress RAR without WInRar Alternative mirror of Automator script.


rar, archive, compression, OS X

Create a Javascript two-dimensional array

var a = new Array(4);  
for (i = 0; i < 4; i++) {  
  a[i] = new Array(4);  
  for (j = 0; j < 4; j++) {  
    a[i][j] = "[" + i + "," + j + "]";  

This creates an array with the following rows:

[0,0] [0,1] [0,2] [0,3] //Row 0
[1,0] [1,1] [1,2] [1,3] //Row 1
[2,0] [2,1] [2,2] [2,3] //Row 2
[3,0] [3,1] [3,2] [3,3] //Row 3

Links and resources:

Mozilla developer, Javascript: Two-Dimensional Arrays


javascript, array, 2d array

Remove a homebrew-installed package and all dependencies

You have to check orphaned dependencies against those Homebrew itself requires:

brew rm thing_to_remove
brew rm $(join <(brew leaves) <(brew deps thing_to_remove))


$ brew rm ruby
Uninstalling /usr/local/homebrew/Cellar/ruby/1.9.3-p194...
$ brew rm $(join <(brew leaves) <(brew deps ruby))
Uninstalling /usr/local/homebrew/Cellar/gdbm/1.10...
Uninstalling /usr/local/homebrew/Cellar/libyaml/0.1.4...
Uninstalling /usr/local/homebrew/Cellar/pkg-config/0.25...

Links and resources:

GitHub: Add an option to brew rm to uninstall / remove a package, including all it's dependencies. StackOverflow: Uninstall / remove a Homebrew package including all its dependencies


homebrew, brew, os x, uninstall, dependencies

Get series of n grouped values from a Ruby array, like an extended hash

Say you want to loop through groups of three values at a time:

['Home', '/', 'The home page',
'Page Two', 'two', 'The second page',
'Page three', 'three', 'The third page'
].each_slice(3) do|label,link,title|
   li {a label, :href => link, :title => title}
   # print "#{label} | #{link} | #{title}\n"

Example from Ruby micro-framework Camping. To use without html markup uncomment the print statement. (note: Ruby < 1.8.7 will need require 'enumerator' for each_slice)

Links and resources:

Stack Overflow, reply to: the right way to iterate through a Ruby array


ruby, array, hash

Use a lambda in Ruby to make an array from hash pairs

def with_names(fn)
  result = []
  [ ["Christopher", "Alexander"],
    ["John", "McCarthy"],
    ["Joshua", "Norton"] ].each do |pair|
      result << fn.call(pair[0], pair[1])
l = lambda { |a, b| "#{a} #{b}" }

Links and resources:

RubyMonk: functional programming


ruby, lambda, hash

Change default column wrap in TextMate

Open up Terminal and type:

defaults write com.macromates.textmate OakWrapColumns '( 60, 70, 80, 120 )'

Links and resources:



textmate, wrap, column, defaults

Regex to wrap bracketed numbers in a cite tag

Includes hyphenated series (n-n).

find: \((.[\d-]+)\) replace: <cite>($1)</cite>

Links and resources:


grep, regex, textmate

Stop git tracking deleted files

git rm $(git ls-files --deleted)
git add -u

git status will list them to be deleted at the next commit.

Links and resources:


git, deleted

Add a file or directory to an existing .gitignore file

echo "path/to_files/" >> .gitignore

Links and resources:


git, ignore

A basic Javascript constructor

function Thing(param1, param2) {
    this.property1 = param1;
    this.property2 = param2;

var my_thing = new Thing(eg_number, "eg_string");

Or alternative syntax:

var Thing = function(param1, param2) {
    this.property1 = param1;
    this.property2 = param2;

Or use object literal sytnax:

var Thing = {
    property1: param1,
    property2: param2

Links and resources:


javascript, constructor

Setting RVM default Ruby

View your installed version of Ruby with rvm list, and copy the version you want as a default.

rvm alias create default ruby-1.9.2-p290 or in latest RVM docs(?):
rvm --default use 1.9.2-p290 which sets the default Ruby for all new terminal windows (the alias method didn't do this on OS X 10.5.8 for new windows?).

Links and resources:


rvm, ruby, default

Debian apt-get cheat sheet

aptitude is the text-based interface to the Debian GNU/Linux package system. Debian package names end in .deb


install {pkg name} or upgrade to latest
remove {pkg name} (but keep configuration files)
--purge remove {pkg name} (remove all files)
upgrade {pkg name} find multiple upgrades
  display the list of all available upgrades (updates) using -u option,
  to upgrade all shown packages, hit 'y'
dist-upgrade (after update) upgrade Debian
 - intelligently handles changing dependencies with new package versions
 - apt-get has a "smart" conflict resolution system


apt-cache search "Text-to-search"
 - search for package/package description before installing (if you don't know the exact name)
apt-cache depends {name} list each dependency of a package

dpkg - install, query uninstall packages

dpkg --info {.deb-package-name} get package information
dpkg -l list installed packages
dpkg -l | grep -i 'pkg name' see if a package is installed
dpkg -L {pkg name} list files provided (or owned) by the installed package
dpkg -S {/path/to/file} find what package owns a file
dpkg -s {package-name} | grep Status find out if Debian package is installed or not

Links and resources:

Linux debian package management cheat sheet, apt-get cheat sheet, dpkg cheat sheet


debian, linux, apt-get, cheatsheet

Java: compiling and directory hierarchy

dot-separated classnames need separate directories - in the src directory make a hierarchy that mirrors your package hierarchy e.g. given a class named com.elharo.math.Fraction put Fraction.java inside the math directory:

src com elharo math Fraction.java

Compiling Java code is tricky because you need to keep track of several related but different things:

By default, the javac compiler thinks these are all the current working directory, which is almost never what you want. Consequently, you need to explicitly specify each of these elements when you compile.

If you use the Java CLASSPATH (because you're only compiling to the same directories every time, say if you only have one Java project), it needs both the source and target directory because the compiler needs to find the .class and .java files each target file imports (check this).

Links and resources:

IBM Developer work: Java classpaths


java, classpath

github error: SSL certificate problem, verify that the CA cert is OK

Quick fix (don't use --global if it's just for one repo) disable the SSL CERT verfication: git config --global http.sslVerify false

Links and resources:

SSL certificate rejected trying to access GitHub over HTTPS behind firewall


github, git, SSL, certificate

Installing Fortran on OS X as a dependency of scipy (or of R)

If pip install scipy or easy_install scipy fail with pip giving timeout: timed out or easy_install failing with:

error: SandboxViolation: open('/dev/null', 'w') {}

The package setup script has attempted to modify files on your system
that are not within the EasyInstall build area, and has been aborted.

This package cannot be safely installed by EasyInstall, and may not
support alternate installation locations even if you run its setup
script by hand.  Please inform the package's author and the EasyInstall
maintainers to find out if a fix or workaround is available.

the issue for me was that scipy requires Fortran, which doesn't come with OS X and wasn't installed on my (Leopard) system with Xcode 3.1.4.

A search for the latter error turned up a red herring: issue93 in setuptools; while searching for numpy and scipy on OS X might turn up Calvin Cheng's instructions, which are more useful, except that the link to the OS X GFortran binaries at gcc.gnu.org appears to be broken (for me, gcc.gnu.org never loaded), but there's an alternative source from a page on R for OS X, although (unsure of whether 32- or 64-bit was the way to go for my OS X 10.5 system) I used the GNU Fortran installer for "OS X 10.4 or higher" on this "tools for R" page (although the latest GFortran 4.2.4 is also offered for 10.5, and these are all OS X .dmg installers). I also used the OS X scipy installer, and all was well. However, my virtualenv now has to use my system Python libraries, as scipy wouldn't install inside a virtual env with no site packages. Sigh.

Fortran is also required for the R language.

Links and resources:


python, OS X, scipy, GNU Fortran, GFortran, [R], CRAN, virtualenv

How to scale SVGs for responsive web design

Make sure the SVG root element has a viewBox attribute e.g.
<svg version="1.1" viewBox="0 0 300 185">
where first two parameters (0 0) are the origins of the viewBox, the second two are the width and height.

Links and resources:

Autoscaling an SVG embedded in HTML on window resize, Making Sense of SVG viewBox's Madness


SVG, responsive design

Stretch and scale CSS background

Use the CSS 3 property background-size. To preserve the aspect ratio use the values background-size: cover;, contain; or 100% 100%;. Louis-Rémi built a polyfill for IE8.

Links and resources:

Stretch and scale CSS background


css, css3, background, background-image, scale

Clear screen while in the python shell

Use the system's command in *nix:

>>> import os
>>> os.system("clear")

Or in a function:

>>>def cls():
...    os.system("clear")

Links and resources:

Any way to clear python's IDLE window?


Python, terminal, shell, IDLE, clear screen

What does init do in Python classes?

This ensures that all subsequent classes inherit the functionality defined in __init__:

>>> class MyClass(object):
...     i = 123
...     def __init__(self):
...         self.i = 345
>>> a = MyClass()
>>> print a.i
>>> print MyClass.i

Links and resources:

Python __init__ and self what do they do?, Python, __init__ and self confusion


Python, __init__, self

Two examples using Ruby's inject

A function to add any list of numbers:

def add(*numbers)
  numbers.inject(0) { |sum, number| sum + number }

puts add(1)
puts add(1, 2)
puts add(1, 2, 3)
puts add(1, 2, 3, 4)

Multiply a list of numbers by two if the number is even:

[1, 2, 3, 4, 5, 6].inject([]) do |result, elm|
  result << elm * 2 if elm % 2 == 0
# => [4, 8, 12]

Grouping a list of words by the first letter of the word:

["alpha", "bravo", "charlie", "bark", "almond"].inject({}) do |result, elm|
  result[elm[0].to_sym] ||= []
  result[elm[0].to_sym] << elm
# => {:a=>["alpha", "almond"], :b=>["bravo", "bark"], :c=>["charlie"]}

Links and resources:

rubymonk lesson 69, Map If in Ruby and an Introduction to Ruby’s Inject


ruby, inject

Using Javascript libraries for enabling media queries in IE<=8

There are two main Javascript libraries with the following features:

Respond.js : simply enables min-width and max-width, focused mainly on Internet Explorer 8 and under. Also, read the caveats closely as there are many edge cases! css3-mediaqueries.js : covers all media queries, and also IE 5+, Firefox 1+ and Safari 2

Links and resources:

How to get IE8 to understand CSS media queries


css3, media queries, IE8, internet explorer

Ruby if-then, and array from YAML data in one erb line

If a Yaml array planets exists, create a Ruby array p from it:


- Sun
- Moon
- Venus


<% p = []; @item[:planets].each do |i| p << i end %>

Links and resources:

Writing if statement in one line with elsif condition


yaml, ruby, erb

Illustrator "collect in new layer" defaults to outline view

If the "eye" icon for the item in the Layers palette shows an "outline" eye, cmd-click it to change to "preview".

Links and resources:

Illustrator: About layers


adobe, illustrator, layers, outline view

Create an equilateral triangle in CSS

To calculate the desired height, add the left and right borders (the total width) and multiply by 86.6%:

w * 86.6/100 = h
(50 + 50) * 86.6/100 = 86.6

To calculate a desired width from a given height:

h * 115.470054/100 = w
100 * 115.470054/100 = 115.470054

Example CSS:

#triangle-equi {
  margin: 0 auto;
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 86px solid green; /* 86.6% of width (50+50) */

Or use em for measurements to get fractions:

  border-left: 5em solid transparent;
  border-right: 5em solid transparent;
  border-bottom: 8.66em solid red;

Links and resources:

Equilateral Triangle Calculator, The Shapes of CSS


css, geometry, triangle, mathematics

Using RSA for ssh, sftp, rsync, etc. without a password

If you're developing websites and frequently logging into the server via a command line to upload files (e.g. for static site generator nanoc's nanoc deploy command) you can set things up so you don't have to enter (or remember) the user's password every time.

Open a command-line terminal while logged as the user who will run scp, ssh or rsync (i.e. when making/uploading websites).

To find out if you already have an rsa keypair enter cd ~;ls -al - if you see an .ssh folder, enter cd .ssh;ls and check for the keys: id_rsa and id_rsa.pub

If there is no .ssh folder, make sure you're at the root level, create it and enter it:

cd ~
mkdir .ssh
cd .ssh

Create the rsa keypair

Now you're inside the .ssh folder, create a private and public keypair by typing:

ssh-keygen -t rsa

When prompted "Enter file in which to save the key", press return or enter to name the pair with the default name "id_rsa".

Do the same for "Enter passphrase", otherwise you will need to enter a passphrase each time you log in, which defeats the password-free purpose.

You will see something like the following:

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
14:f0:06:ba:8c:d7:d0:b7:33:28:ca:38:fa:30:24:52 username@.local
The key's randomart image is:
+--[ RSA 2048]----+
|         o =o    |
|        o.+ .o   |
|   = o .o  o     |
|  . B .  = o     |
|   o =           |
|    E .o..o .    |
|    .            |
|        ..+o.    |
|                 |

You normally won't need the randomart image, so it can be ignored, or you can copy and save it in a text file.

Create a public key folder for a user on your server (they will need to accept your key)

You will need to do this for each user on the remote machine where you upload website files via a terminal. If you're managing multiple websites, your server will likely have a user account for each website. If you only manage one, you only need to do this once.

UPDATE 2019: shortcut ssh-copy-id should be available on most operating systems:

ssh-copy-id -i /path_to_key_here/.ssh/id_rsa.pub user@server_or_domain optional port: -p 778899

Test this by logging in with ssh -p '778899' 'user@server_or_domain' (port if necessary)

Previous instructions (redundant but retained for completeness)

Make sure you're still in the .ssh folder and can see the keypair:

cd ~.ssh;ls

If you see "id_rsa.pub" and "id_rsa" both listed, login in to the remote user's account on the server:

ssh username@servername_or_ip

Enter the usual password, make sure you're at the user's root directory, and check for an .ssh directory:

cd ~
ls -al

If there isn't an ".ssh" directory, create it, set permissions that restrict everyone except that user, and cd (change directory) into it:

mkdir .ssh
chmod 700 .ssh
cd .ssh

Upload the public key and save its contents

Create an "authorized_keys" file to hold your public key data and set the file's permissions:

touch authorized_keys
chmod 600 authorized_keys

Confirm the exact path from the server's root folder to the user's .ssh folder:


Copy this path (something like /home/username/.ssh) and use it in the following command, which will securely copy (scp) your local public key file to the user's .ssh folder. Use the same "username@servername" you used to log in via ssh:

scp id_rsa.pub username@servername:/home/username/.ssh/id_rsa.pub

Use ls to check that the key has uploaded—if you see the two files "authorized_keys" and "id_rsa.pub", enter the following command to copy the contents of your public key to the "authorized_keys" file:

cat id_rsa.pub >>authorized_keys

If you enter less authorized_keys you should see a string of text, which means that your public key is now stored in "authorized_keys". Type q to exit less, and delete your public key file:

rm id_rsa.pub

You should now be able to logout of ssh and login again as before, but without being prompted for a password.

Note: if the user's home directory on the server is accessed via NFS, then permissions for .ssh has to be 711 and "authorized_keys" 644.

Links and resources:

How To scp, ssh and rsync without prompting for password, SSH and SCP: Howto, tips & tricks


rsa, rsa keys, id_rsa, ssh, sftp, rsync, password, server

Updating to a more recent version of Ruby on OS X with Homebrew

Always start by checking Homebrew is healthy and up-to-date:

brew update
brew doctor


brew install ruby

Check where the new Ruby gems are:

gem environment
     - /usr/local/Cellar/ruby/2.0.0-p247/lib/ruby/gems/2.0.0
     - /Users/admin/.gem/ruby/2.0.0

Like rvm, you can now install gems without sudo for your user (not system-wide):

gem install (gem_name)

Homebrew advises:

NOTE: By default, gem installed binaries will be placed into `/usr/local/opt/ruby/bin`

You may want to add this to your PATH.

so you will probably need to add /usr/local/opt/ruby/bin to the end of the colon-separated PATH variable in .bash_profile (if you already have one—in your home folder—create the file if you don’t already have it) e.g.:
export PATH=/usr/local/bin:(more paths here):/usr/X11/bin:/usr/local/opt/ruby/bin

Installing Ruby gems not working with Home Brew


ruby, homebrew, ruby gems

Reverse a string in Javascript


Beware that this fails with Unicode string (e.g. accented characters, etc.)—for those, use Mathias Bynens’ Esrever library.

Reversing strings in JavaScript, How do you reverse a string in place in JavaScript?, A Unicode-aware string reverser written in JavaScript


javascript, reverse, string

Install node.js with Homebrew

Run the commands below in order:

brew update
brew doctor
brew upgrade node

How to install latest version of Node using Brew


homebrew, brew, node

printf() variable substitution in Javascript consoles

var userName = 'Dave', color = 'purple', age = 100;
console.log("My name is %s and I am age %d. I like the colour %s.", userName, age, color);

The substitution strings (Formatting not yet supported for integers or floats):

Jason Strimpel: printf() in JavaScript???


javascript, printf, console.log

Export/import multiple images to/from Photoshop layers

Import multiple images as layers with Adobe Bridge

Open Adobe Bridge, navigate to the directory with the images and select all the files you want in layers.

In the menu bar select Tools > Photoshop > Load Files into Photoshop layers.

Export multiple layers as separate images

Files -> Scripts -> Export Layers to Files…

Photoshop: Importing multiple images into multiple layers, How to Export Layers in Photoshop CS5 as Separate Images


photoshop, adobe bridge, multiple images, layers

Share an iCloud calendar in iCal 4 (OS X 10.6 Snow Leopard)

If you use Snow Leopard and want to access/edit calendars that you have in iCloud (say from more recent OS X versions or iOS devices), older advice is far too complex—the most recent iCal 4 in Snow Leopard makes this possible. Follow these steps:

Getting to your iCloud calendar from iCal 4 (OSX10.6) or a CalDAV client, 10.6: Add iCloud Calendar in iCal (out of date but a good reference)


caldav, calendar, snow leopard

Loading a CDN resource on a secure site under HTTPS

For example, the recommended CDN for Font Awesome shows the URL without an HTTP-protocol prefix:
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

So if your site is running under https (TLS/SSL), add the appropriate protocol to the start of the URL:

​SSL: How to Move Your Website to HTTPS


https, cdn

Upgrading Node and Ember CLI

This uses the n Node helper package so first, clean the cache and install it:
sudo npm cache clean -f
sudo npm install -g n

Then upgrade node to the latest stable version:
sudo n stable

Or specify a desired version:
sudo n 0.8.21

and - if you like - check the version:
node -v

Finally, uninstall Ember CLI and re-install the latest:

npm uninstall -g ember-cli
npm cache clean
bower cache clean
npm install -g ember-cli

Then upgrade your Ember CLI app.

Upgrade Node.js via NPM Upgrading an Ember CLI App


ember cli, ember, node, upgrade

Install/downgrade to a specific version of Ember CLI

npm install -g ember-cli@0.2.3


ember cli, ember, downgrade, version

Clone an Ember CLI project

Clone the repo:
git clone /path_to_project

Install the project's Node and Bower package dependencies npm install bower install


ember, bower, git

Can't sign in to FaceTime on OS X

Open System Preferences -> Network

Select wi-fi on the left

Click: Advanced -> DNS

Click the + bottom left of the DNS Servers and add


Links and resources:

I Can't Login to FaceTime


facetime, OS X, login

Set up a keyboard shortcut for tab cycling in Atom

Atom has an annoying way of selecting tabs. To get this working like it does in Sublime, TextMate and other apps, go to:

Atom menu -> Open Your Keymap

Add (Sublime):

  'ctrl-tab': 'pane:show-next-item'
  'ctrl-shift-tab': 'pane:show-previous-item'

Or (TextMate, etc.):

  'shift-cmd-[': 'pane:show-next-item'
  'shift-cmd-]': 'pane:show-previous-item'

Restart Atom.

Links and resources:

Keyboard shortcut for cycling through tabs


atom, tabs, keyboard shortcut

Make CSS styles auto-reload in Ember-cli

Install ember-cli-styles-reloader to reload (css|scss|sass|less|styl) without reloading the entire ember-cli app

Install the node module: npm i ember-cli-styles-reloader

Then install into your ember-cli app (for Ember CLI >= 0.2.3) ember install ember-cli-styles-reloader

(If you do this before intalling the node module, you'll get Install failed. Could not find addon with name: ember-cli-styles-reloader)

In your app, this adds "ember-cli-styles-reloader": "0.1.6", (or whatever version) to package.json.

There's an option to animate style changes, but this seems excessive when it's enough to see the changes updated automatically. The ember-cli console outputs Reloading saves-client.css only when you change the stylesheet.

Links and resources:



ember, ember-cli, css, styles, reload

Enable command line tool subl for Sublime Text

If Sublime Text 2 is in the Applications folder, and there's a ~/bin directory in your path, make a symlink to subl:

ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl

Links and resources:

Sublime OS X Command Line


Sublime Text, Sublime, subl, terminal, command line

Create an incremented HTML list in Atom with Emmet

Emmet uses CSS-style shortcuts combined with parameters (over-specific example to illustrate):

ul#my-list>li.list-item*5>{Item nr. $}

Hit cmd--E to get:

<ul id="my-list">
  <li class="list-item">Item nr. 1</li>
  <li class="list-item">Item nr. 2</li>
  <li class="list-item">Item nr. 3</li>
  <li class="list-item">Item nr. 4</li>
  <li class="list-item">Item nr. 5</li>

Links and resources:


atom, atom editor, emmet, emmet.io

Regex to replace LaTex quotes (`') with typographic quotes

Example: the Atom editor follows Javascript Regex syntax, so (to find words, hyphens, commas and spaces enclosed in quotes):

`([\w-, ]+)'

Add whatever other characters you need inside the square brackets [], making sure to escape special characters such as brackets, forward slashes, addition signs, etc. with a backslash \ like this \/\)\+.

Links and resources:


latex, atom, atom editor, regular expression, regex

Uninstall the version 3 or older Xcode ‘Developer’ Folder and Contents

XCode 4.x is installed in /Applications/, while XCode 3.x is installed in /Developer/.

If you've installed a newer version of Apple's XCode but an older version (3.x) is still in the /Developer/ folder, run the following command in Terminal, rather than manually deleting it through the Finder:

sudo /Developer/Library/uninstall-devtools --mode=xcodedir

This keeps other aspects of Xcode intact but removes everything within the /Developer/ folder:

Variations of this command uninstall other components, or the whole of XCode—see the links.

Links and resources:


xcode, apple, os x, developer tools

Create multiple folders/directories from a text file of names

A quick way to create a load of directories with specific names on the command line.

  1. Create the folder/directory to contain the folders/directories you want to create.
  2. Make a text file e.g. 'names.txt' and add the folder names you want on separate lines.
  3. Open a terminal and navigate (cd) to the folder containing the text file.
  4. run cat names.txt | xargs mkdir

Links and resources:

Aaron Lynn, Creating Multiple Folders from a Text File in Terminal


mkdir, folders, directories, create, terminal, xargs

Using pushd and popd to switch directories

When using the command line this is a quick way to move into other directories, then return quickly to the one you’re in.

Example to explain pushd popd

Given a directory structure like this in your home directory:


You could move around like this:

$ cd dir_1
$ pushd dir_2/dir_3
~/dir_1/dir_2/dir_3 ~/dir_1
$ popd
$ pushd dir_2
~/dir_1/dir_2 ~/dir_1
$ pushd dir_3
~/dir_1/dir_2/dir_3 ~/dir_1/dir_2 ~/dir_1
$ popd
~/dir_1/dir_2 ~/dir_1
$ popd

pushd "pushes" your current directory into a list for later, then changes to another directory, like saying "save where I am, then go here"

popd takes the last directory you saved with pushd, removes it from the list and takes you back there.

Run pushd alone to switch between your current directory and the last one you pushed:

$ pushd dir_2
~/dir_1/dir_2 ~/dir_1
$ pushd
~/dir_1 ~/dir_1/dir_2
$ pwd

Links and resources:

‘Moving Around (pushd, popd)’, from Zed Shaw, The Command Line Crash Course


pushd, popd, terminal, directories

How to filter and export XML DayOne entries

There's [jrnl(https://maebert.github.io/jrnl/)], which looks like a great command-line journalling tool, but I couldn't find out how to export only certain tagged entries.

Then there's a Python Day One Export project on GitHub, which will output to various formats, including Jinja templates. Customisable templates live at ~/.dayone_export.

Install using pip via the command-line:

pip install dayone_export

Being PIP, this also installs the requirements. As an example here's the readout from my install (ignore if you want):

$ pip install dayone_export
Collecting dayone-export
  Downloading dayone_export-0.8.3.tar.gz
Collecting Jinja2>=2.6 (from dayone-export)
  Downloading Jinja2-2.8-py2.py3-none-any.whl (263kB)
    100% |████████████████████████████████| 266kB 514kB/s
Requirement already satisfied (use --upgrade to upgrade): pytz in /usr/local/lib/python2.7/site-packages (from dayone-export)
Requirement already satisfied (use --upgrade to upgrade): python-dateutil>=2.1 in /usr/local/lib/python2.7/site-packages (from dayone-export)
Collecting Markdown>=2.5.1 (from dayone-export)
  Downloading Markdown-2.6.5.tar.gz (301kB)
    100% |████████████████████████████████| 303kB 877kB/s
Collecting MarkupSafe (from Jinja2>=2.6->dayone-export)
  Downloading MarkupSafe-0.23.tar.gz
Requirement already satisfied (use --upgrade to upgrade): six in /usr/local/lib/python2.7/site-packages (from python-dateutil>=2.1->dayone-export)
Installing collected packages: MarkupSafe, Jinja2, Markdown, dayone-export
  Running setup.py install for MarkupSafe
  Running setup.py install for Markdown
  Running setup.py install for dayone-export
Successfully installed Jinja2-2.8 Markdown-2.6.5 MarkupSafe-0.23 dayone-export-0.8.3

Then you simply go to the Day One files folder (mine's in Dropbox) (quotes are to handle the space in the 'Day One' folder name, but you could also do this 'Day\ One'):

cd "~/Dropbox/Day One"

Then, in this case for a plain text file of entries tagged 'health':

dayone_export --output my_health_diary.txt --tags health

Day One version 2 is moving to its own cloud, so unsure how this will work then.

Links and resources:


dayone, day one, export, python

Copy a folder and contents in Bash

cp -r [source folder] [destination directory]/[foldername]/

Note the trailing slash.

Links and resources:

Copying folders in Terminal


bash, os x, terminal, copy, folder

Set movie poster frame in QuickTime 10

This feature apparently disappeared, but you can do the following:

Links and resources:

How to set Video Poster Frame


quicktime, movie, poster, frame

Push a new branch to GitHub and set the local branch to track it

You need to set the remote on GitHub

git push --set-upstream origin form-input

You may need to enter your GitHub username and password. If all goes well, you'll get a confirmation message:

 * [new branch]      new_branchname -> new_branchname
Branch new_branchname set up to track remote branch new_branchname from origin.

Links and resources:

Pushing a local branch up to GitHub


github, git, remote, branch, push

Auto-generating a table of contents (TOC) in Quark XPress

Note: if your project is a book, see the first link from Quark for addition instructions.

PDFs can use this feature to create bookmarks and hyperlinks.

  1. Create specific stylesheets (advised) for the number of heading levels required for your TOC, including a tab (and optional fill character) for page numbers
  2. Go to Edit > Lists, click New and name your TOC list in the name field
  3. Choose style sheets from Available Styles, click the right arrow to add to the TOC Styles in List
  4. Choose your preferred heading level from the Level pop-up menu for each style sheet
  5. Choose a Numbering option to specify how page numbers will appear
  6. Choose your specific TOC style sheets from the Format As pop-up menu. NOTE: to avoid duplicate entries do not select the same style sheets in the Name and Format As fields
  7. Click OK, then in the Lists dialog box click Save
  8. Save your document with File > Save
  9. Create pages and linked text boxes to contain your table of contents
  10. Choose Window > Lists
  11. In the Show List For pop-up menu ensure the name of your open project is selected, and your new TOC list is selceted in the List Name pop-up
  12. Click the Update button to scan the project—list entries will appear in the Lists palette bottom pane
  13. Click in the document's text box where you want the TOC to apear
  14. click Build in the Lists palette

Repeat steps 10-14 if pagination or titles have changed.

Links and resources:


quark, xpress, contents, toc, generate

Downgrade node in OS X with Homebrew

add "versions" to Homebrew if it's not already there:

$ brew tap homebrew/versions

search for available versions of node

$ brew search node

You should get a result something like this:

leafnode      llnode        node ✔        node-build    nodebrew      nodeenv       nodenv      
Caskroom/versions/node010                        Caskroom/versions/node4-lts                    
Caskroom/versions/node012                        Caskroom/versions/node5                        

Unlink your current version of node:

$ brew unlink node

and install, replacing 'Caskroom/' with 'homebrew/':

$ brew install homebrew/versions/node5

then finally link the new version and overwrite links to the old - if you want to check, list the files that would be deleted with $ brew link --overwrite --dry-run node5 first, then do:

$ brew link --overwrite node5

node -v should show your new version, in this case v5.12.0

Links and resources:

Downgrade Node.js to a Specific Version Using Homebrew


node, homebrew, downgrade, version

To open “CS5ServiceManager” you need to install the legacy Java SE 6 runtime

Trying to launch any Adobe CS5 app brings up a warning about Adobe CS5Service Manager wanting the old Java 6. Installing OS X (from Lion onwards) comes without Java, which is needed for Adobe's update manager. If you don't need to update Adobe software (e.g. because your're running CS5 on OS X 10.11) you can remove it in Terminal:

sudo rm /Library/LaunchAgents/com.adobe.* 

Warning: opening an older Adobe app will still bring up a dialog warning that it needs the legacy Java 6 version. You can install that from Apple at Download Java for OS X 2015-001 and restart. You may need to re-enter your licence number.

Links and resources:


adobe, java, cs5servicemanager, OS X

MySQL password has expired

Typically, in a script shell, you get the message: "Your password has expired. To log in you must change it using a client that supports expired passwords."

From MySQL 5.7.4 to 5.7.10 (and beyond?) the default value for the default_password_lifetime variable is 360 (a year). For those versions, if you make no changes to this or to individual user accounts, all user passwords expire after 360 days.

To prevent automatic password expiry log in as root:

mysql -u root -p

then, for clients that automatically connect to the server (e.g. from scripts.) change the password expiration settings for those clients:


or just disable automatic password expiration for all users:

SET GLOBAL default_password_lifetime = 0;

To make this permanent, add it to the/a MySQL my.conf file. This is usually at /etc/mysql/my.conf but may not exist by default. Mac OS X Homebrew MySQL installs add a default conf file in a different location but MySQL may need it in a more familiar location. In my case it's /usr/local/etc/my.conf so I added:
default_password_lifetime = 0

Run mysqld to validate it.

See: brew-install-mysql-on-mac-os and for-homebrew-mysql-installs-wheres-my-cnf.

Links and resources:


mysql, password, expired

Use a project-specific version of Ember and Ember-cli

To avoid the globally installed version of Ember (installed with npm install -g ember) first, install ember-cli in the project with npm, then install Ember using Bower, than initialise the project:

install ember-cli and save to as dependency to package.json:
npm install ember-cli --save

(optional) create a bower.json file:
bower init

install your preferred version of Ember e.g.:
bower install ember#2.13.0 --save

In your project directory, if you check the installed version with ember -v it should be different to your globally installed Ember-cli (to verify the Ember version, either do Ember.VERSION in the browser console or look inside /bower_components/ember.js where you'll find the version in the comment at the top.

Links and resources:


ember, ember-cli, javascript

MariaDB/MySQL Homebrew: Can't read dir of '/usr/local/etc/my.cnf.d'

After installing MariaDB using Homebrew, trying to start using mysql -uroot gives:

mysql: Can't read dir of '/usr/local/etc/my.cnf.d' (Errcode: 2 "No such file or directory")
Fatal error in defaults handling. Program aborted

Solution: open the config file at /usr/local/etc/my.cnf with your editor and comment out the following line:

!includedir /usr/local/etc/my.cnf.d

like this:

# !includedir /usr/local/etc/my.cnf.d

Some solutions suggest manually creating the my.cnf.d folder at: /usr/local/etc/my.cnf.d but apparently brew prune will remove it.

Links and resources:

MariaDB homebrew install errors (answer)


mariadb, mysql, homebrew, os x

Installing Python 2.7 on OS X with Homebrew

For a clean version of OS X (10.13 High Sierra), with XCode and Homebrew installed.

The OS X system Python has some shortcomings and it's better to manage programming language software yourself rather than depend on system permissions, updates, etc. You can check the system Python and its location:

python --version
Python 2.7.1

which python

Return to these after installing Python with Homebrew. So, do some housekeeping before any new installs (will generate long readouts):

brew update
brew doctor
brew cleanup
brew prune

Then check which Python version is available via Homebrew:

brew info python
python: stable 3.6.5 (bottled), devel 3.7.0b3, HEAD

So for Python 2:

brew info python2
python@2: stable 2.7.14 (bottled), devel 2.7.15rc1, HEAD

The instructions on the Homebrew site say brew install python@2 but (without thinking) I did:

brew install python2

which worked fine. Homebrew will do some housekeeping, then tell you:

Installing dependencies for python@2: gdbm, openssl, sqlite

Now check the Homebrew-installed Python:

python --version
Python 2.7.14

which python

which python2 will give you:


because they both link to /Cellar/python@2/2.7.14_3/bin/pydoc2.7 so just python is fine, unless you also installed Python 3 with Homebrew, in which case be explicit: python2.

Upgrade pip and setuptools

You'll also see that pip and setuptools are also installed, in the location where Homebrew keeps everything tidy:

which pip

Update them:

pip install --upgrade pip setuptools

Now pip install <package> will install the chosen package into the Homebrew-installed site-package directory /usr/local/lib/python2.7/site-packages

Install virtualenv

No Python development environment is complete without virtualenv and (to make using it easier) virtualenvwrapper. Note: DO NOT sudo—it's not required for Homebrew installations—the whole idea is to keep the system-wide environment clean:

pip install virtualenv
pip install virtualenvwrapper



python, python2, homebrew, os x, pip, virtualenv

Setting up virtualenvwrapper for Python in OS X

Once you have pip and virtualenv installed:

pip install virtualenvwrapper

The recommendation is then to add the following lines to one of the bash initialisation files although .bash_profile is the recommended one (see "Conflicting information" below):

export WORKON_HOME=~/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

The above will be fine if you've installed Python with Homebrew and are not using the system Python.

mkdir ~/.virtualenvs

Enable pip install only inside a virtualenv

To ensure you install packages to your active virtual environment while using pip install, you can also add:


pip will then remind you to install packages in an activated virtual environment:

pip install some_package
Could not find an activated virtualenv (required).

See Requiring an active virtual environment for pip

If you want to continue working in the same Terminal window, reload the .bash_profile file.

source ~/.bash_profile

Conflicting information on the web

There are several opinions/options about:

e.g. export WORKON_HOME=$HOME/.virtualenvs where either $HOME or ~/ will ensure that the folder for your virtualenvs is created in your home directory e.g. on OS X: /Users/yourusername/.virtualenvs (The leading . hides the folder in desktop windows).


From man bash:

       The personal initialization file, executed for login shells
       The individual per-interactive-shell startup file

Links and resources


python, virtualenv, virtualenvwrapper, bash, bash_profile

pip install MySQL-python fails

MySQL-python is outdated and can fail to install with a stack trace that ends error: command 'clang' failed with exit status 1. It appears mysqlclient (forked and updated from MySQLdb and also with python3.3+ support) is a good replacement:

pip install mysqlclient

Links and resources:


python, MySQL, MySQL-python, mysqlclient

Get out of vi/vim editor for GIT in VSCode (or anywhere)

Typically when a commit message comes up, say after a merge, vi or vim appears (or your default editor - this is for vi/vim).

:wq or :x (shortcut) and hit return.

There’s no need to esc as the : will place the cursor ready for the wq or x command.

Links and resources:


vi, vim, vscode, git, osx

Upload SSH key to server

SSH has a built-in command for this:

ssh-copy-id -i ~/.ssh/id_rsa.pub user@server

Test this by logging in with ssh -p '778899' 'user@server_or_domain' (port if necessary)

Links and resources:


ssh, ssh-copy

Change owner and group for a directory and contents

chown -R username:groupname foldername


chown -R root:root Python2.7.0


chown, chgrp, linux, directory

Deploy a website to a server using GIT

This method works for any site, but is specific to the structure set up by static site generator Nanoc. It was sparked by repeated issues with rsync.

in "nanoc.yaml":

deploy: default: kind: git remote: ssh://USER@IP:PORT/PATH_TO_BARE_REPO.git branch: master forced: true

Not sure if "forced" is necessary, but it's pretty quick for even a large site anyway.

On the server in "SITE_REPO.git/hooks/post-receive":

#!/bin/sh git --work-tree=/PATH_TO_SITE_ROOT --git-dir=PATH_TO_BARE_REPO.git checkout -f

You can also create a global git pushall alias on your local system to push to the server and the live site with one command.


git, nanoc, server, deployment

Fix "nginx.service is masked"

use sudo systemctl unmask nginx.service

root/# service nginx status
   Loaded: masked (/dev/null; bad)
   Active: inactive (dead) since Wed 2020-03-18 16:34:01 CET; 6h ago
   [more info here]
root/# service nginx start
  Failed to start nginx.service: Unit nginx.service is masked.
root/# sudo systemctl unmask nginx.service
  Removed /etc/systemd/system/nginx.service.
root/# service nginx start

Links and resources:


nginx, server, masked, unmask

Show hidden files in OS X

In *nix-based systems like OS X these are prefixed by a full stop (dot) . and the quickest way to show them is to click in the finder window where you want to see them, and his CMD + SHIFT + .. This toggles their visibility on/off.

The older (and longer but permanent) way to show/hide them all is to open Terminal and type:

defaults write com.apple.finder AppleShowAllFiles YES or NO

Then restart the Finder:

If you want a shortcut command in Terminal, the link below explains how.

Links and resources:


os x, apple, hidden files, finder

perl: warning: Setting locale failed

When running Perl process you get:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LANG = "en_GB.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

On Debian or Ubuntu:

comment in the required locale: /etc/locale.gen (they may all be commented out by default)

run: locale-gen

Links and resources:


perl, locale

List all installed Perl modules

Command-line (example from a running server):

Available commands are:
   l    - List all installed modules
   m    - Select a module
   q    - Quit the program
cmd? l
Installed modules are:
   [...more here]

Links and resources:


perl, modules, cpan

Fix unwanted horizontal web page scrolling

Where this is caused by elements that are too wide for the viewport:

  1. open the website in a browser
  2. paste the JavaScript below into the browser console
  3. identify the offending elements from the red border
let w = document.documentElement.offsetWidth;
let t = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
let b;
while (t.nextNode()) {
  b = t.currentNode.getBoundingClientRect();
  if (b.right > w || b.left < 0) {
    t.currentNode.style.setProperty('outline', '1px dotted red', 'important');

Links and resources:


web, development, design, css, viewport, html, scroll

GIT not recognising (so GitHub not getting) case changes in filenames

On the command-line, check whether ignorecase for GIT is set to true or false:

git config core.ignorecase

If it returns true, set it to false:

git config core.ignorecase false
You might need sudo to run the command successfully.

Links and resources:


git, github, case-sensitivity, uppercase, lowercase, path, filenames, foldernames

Apple Mail crashes on opening

  1. Open Mail while holding the Shift key, which opens it without any message or mailbox selected.
  2. If Mail opens with no windows visible, choose File > New Viewer Window.
  3. Hide the message viewer portion of the window by dragging the thin separator bar between it and your list of messages until Mail shows only the list of messages, not the message viewer. You can now only see messages by double-clicking a message.
  4. Click the affected message once to select it without opening it, press Delete.

Links and resources


apple, mail, email, crash

GitHub retains duplicate files after case changes

After setting:

git config core.ignorecase false

…then changing case in filenames and pushing to GitHub, the old filenames are preserved as separate files even though they don't appear in the local repository. Setting git config core.ignorecase false overrides Windows and Mac OS X behaviour that ignores case changes and isn't recommended.

Instead, you need to explicitly tell git to update case changes in filenames by using git mv instead of globally setting ignorecase (use mv -f to force the change if necessary):

git mv Contact-Me.html contact-me.html

However, this can be tedious when many files have had case changes, so clearing the git cache will force git to see the changes and push them to GitHub:

git rm -rf --cached .
git add .
git commit -m "cleared cache for case changes"
git push

Links and resources


git, case-sensitive, case change, capitalization

Bitwarden extension not appearing in Safari

If the Bitwarden extension isn’t appearing after a Safari update in “Safari > Settings > Extensions”, and you previously enabled it, go to:

"Safari > Settings > Developer" and check "Allow unsigned extensions".

If the Bitwarden extension is already installed, you can paste this command into Terminal to check that it exists:

pluginkit -mAvvv -p com.apple.Safari.web-extension

The readout might look something like this:

                Path = /Applications/Bitwarden.app/Contents/PlugIns/safari.appex
                UUID = 66A4F876-7E61-4715-9C1F-EA61B6ACBA08
           Timestamp = 2024-01-30 17:02:58 +0000
                 SDK = com.apple.Safari.web-extension
       Parent Bundle = /Applications/Bitwarden.app
        Display Name = Bitwarden
          Short Name = Bitwarden
         Parent Name = Bitwarden
            Platform = macOS

There are many suggestions out there about this, involving re-installs etc., but this gets around the issues of needing to install Bitwarden only from the App store. The links below are for reference only and do not follow the above procedure.

Links and resources:


bitwarden, safari, extension, plugin

git branch -a shows deleted branches

To remove these stale branches:

Set a config flag to do it automatically in ".git/config": git config -global fetch. prune true or remotely for origin: git config remote.origin.prune true

Links and resources:


git, branch, prune, delete, remote, merged