James's UNIX/computer hints page

This page is a collection of notes, partly for my own reference, on how to do various things with computers that I found difficult, or that took me a while to figure out. I want to have this information somewhere where other people can theoretically access it so I don't feel like I wasted my time figuring it out :).


Installing Solaris 9 on a SPARC machine using non-Sun hard disk and CD-ROM

The first thing to know is that Sparc machines expect the internal disk (well, the first one) to be SCSI ID 3, not zero as I had assumed. The internal CD-ROM is assumed to be SCSI ID 6. So, if you want it to work when you type `boot cdrom' at the `ok' prompt, the CD drive must be set to ID 6. I don't think these IDs are required, but they make life easier.

Secondly, you may get a message like `can't open disk label package' or a message about the wrong magic number: Referring to your CD drive, this seems to mean that the machine can't read the CD. However, referring to your hard disk, it simply means that the drive hasn't been formatted in a Solaris-friendly way. The installer won't be able to fix this for you, so you need to format it manually. Boot the system from the software disk 1 by typing `boot cdrom -sw', and you'll be taken to a single-user-mode command prompt, where you can run the program `format'. Tell it `y' when it asks about creating a new disk label, then format the disk. After this, solaris should install correctly.


How to install Solaris 9 on a sparcstation with less than 96MB of RAM

If you're trying to install Solaris 9 and you have less than 96MB of memory, running the first of the three disks (the install disk) will not allow you to continue. To get around this, simply boot from the first of the two software disks.

Under Solaris, the /home directory cannot be modified

If you can't create new users under solaris because the /home directory doesn't allow writing, then /home has been `automounted' by the automount program. The idea is that all systems mount the users' home directories from a central NFS server. If you don't want this, edit /etc/auto_master and comment out the line that references /home, then run `automount' to re-read the file.

How to run X apps as root, or another user

I used to do ugly things like ssh to another user, or perform some form of `xhost +', to allow root's apps to display in my X server. A better way is to use xauth to give root (or another user) the ability to draw on your desktop.
# xauth merge /home/jim/.Xauthority
Replace the path to my home directory with your own. Now root will be authorised to use your X server.

Alternatively, you can use 'sudo' to run apps that need root privileges, as this seems to keep your display settings and Xauthority intact.


(Under Gnu/Linux) how to mount an ntfs partition so that non-root users can read it

The line in your /etc/fstab should be of the form:
/dev/hda1       /windows        ntfs    defaults,umask=0000     0 0
The relevant part is the umask, which essentially allows all permissions (it's a zeroed bitmask) for all users.

Debian: How to access a USB digital camera as a normal user using hotplug

Packages to install: Then:

MacOS X: How to burn CDs from the command line

You can use packages from fink, and this simple script, to burn CDs from the command line. This has the added advantage of being able to burn more than the 660mb the Finder's burning feature limits you to.

Required packages from fink:

You can now write CDs using the appropriate syntax. To simplify this, I made the following script:
#!/bin/bash

if [ "$2" == "" ] 
then title="Untitled CD"
else title="$2"
fi

echo "Calling mkisofs on folder $1 with title $title"
mkisofs -V "$title" -o /tmp/currentcd.iso -J -r "$1"

echo "Calling cdrecord"
cdrecord -v dev=IODVDServices /tmp/currentcd.iso

rm /tmp/currentcd.iso

echo "Done making CD."
Put this somewhere in your path, then call it with
$ sudo [script_name.sh] folder_with_cd_contents/ "Label of CD"
The sudo is not required, but it allows cdrecord to set a higher priority, minimising the chance of buffer underruns.


Linux 2.6: Browsers take too long "resolving host"

If your browser seems to take an anomalously long time to load pages, pausing with a message 'resolving host' for more than say three seconds, check to see whether you have ipv6 compiled into your kernel. If so, remove the module or recompile your kernel without this feature.

I found this here


How to forward a range of ports across your iptables firewall

To forward a range of TCP ports to a particular machine inside your NATed network, use a line like this:

iptables -t nat -A PREROUTING -p tcp --dport 6881:6999 -i ppp0 -j DNAT --to 192.168.1.6
In this example, I'm forwarding connections aimed at ports from 6881 to 6999 on my network's external interface, ppp0, across my NAT machine and into the server at 192.168.1.6. (These are the ports to forward for BitTorrent).

If you want to forward a single port to a different port inside your network, specify it after the destination IP address, like this:

iptables -t nat -A PREROUTING -p tcp --dport 81 -i ppp0 -j DNAT --to 192.168.1.6:80
This will cause traffic aimed at [external_ip]:81 to be forwarded to 192.168.1.6:80.


How to plot simple graphical data from a file with R

Debian package r-base

Starting with a text file of the form:

#Blockgap       Similarity
0               0.997525
1               0.997678
2               0.997433
....
The following two lines will produce a plot of this data:
x <- read.table("filename.txt")
plot(x)
To alter the line/point style, you can say plot(x, type="l") for lines, for example.

To get the plot as a file for printing, latex-ing, etc, give the incantation postscript(file="myoutputfile.ps") before running plot.


How to remove a lot of floor or ceiling outlying data points in R

If you have data with valid values but a scattering of outlying items with a particular value (such as ones or zeroes in a cosine measure) which disturb the zen qualities of your graph, you can exclude them manually in R without forshortening the graph (a correctly sized gap will be left, rather than erroneously closed up). (thanks to Steve for working this out.)

To remove all the values of 1 from a graph derived from a table:

x <- read.table("filename.txt")
tmp <- x[,2] == 1.0
plot(x[!tmp,])


In bash, how to test whether an environment variable exists before you set it

If you want to set an environment variable only if it hasn't yet been set, use this:

if [ -z "$MYVARIABLE" ]
	then MYVARIABLE="value"
	export MYVARIABLE
fi
I'm using this to allow Terminal.app in MacOS X to set its DISPLAY properly for X11, without breaking the DISPLAY settings of remote hosts connecting to the machine.


In bash, how to truncate (crop) a string variable

from the weird-syntax department

$ mystring="this.html"
$ echo ${mystring%%.*}
this
Where '.' can be any character. I use this to get the names of files without their extensions.

To get the end of a string, use # instead of %. So this also works:

$ mystring="this.html"
$ echo ${mystring##*.}
html


Bash: How to do something to multiple files with a for loop

Imagine you have a directory of files, and you want to pipe them through a program and have the output stored in a separate set of files. You can't do that with just a wildcard, as the output will only go to one file. Here's the solution:

Imagine we have three files, one, two and three. We want to send them through a program 'strip', and put the output to [file].stripped:

for myfile in *; do strip < $myfile > $myfile.stripped; done


MacOS X: How to compile something that links to a library from Fink

I'm using the id3 library. Under linux, I can compile as follows:

$ g++ -lid3 progname.cc -o progname
This is because the id3 lib is in my default include path (/usr/include). Fink libraries go into /sw/include, which isn't in gcc's include path. We fix this as follows:
$ g++ -I/sw/include -lid3 progname.cc -o progname
(i.e. setting a custom include path). Now we get this error:
ld: can't locate file for: -lid3
A linker error. What's happening is we've told gcc where to find the headers for the id3 lib, but not the binaries. We have to specify that too so the info can be passed to the linker:
$ g++ -I/sw/include -L/sw/lib -lid3 progname.cc -o progname


Linux 2.6: How to set up and use a DVD burner in Debian

This is much simpler than it used to be (and much simpler than most tutorials imply). It used to be that you had to set up your IDE burner as a SCSI-emulated drive, but Linux 2.6 removed this requirement. Just make sure you have the sg module availabe to your kernel. Then install the packages mkisofs and dvdrtools.

Then the following commands will master and burn a DVD for you, assuming /dev/hdd is your burner's IDE address, and mydirectory/ contains your data:

mkisofs -udf -V "My DVD title" -o mycurrentcd.img -r mydirectory/
dvdrecord dev=/dev/hdd -dao currentcd.img
You must run this second line as root, or using sudo.

In fact, dvdrtools has a competitor package, dvd+rw-tools. In this package is the all-in-one tool growisofs, which combines mkisofs's functionality with a way to burn directly to a DVD. It seems to work (simply pass it the option "-Z /dev/hdd" to tell it where your burner is), and gives slightly better progress reporting, but the above method works perfectly too.


How to make backspace work `properly' in Vim

For some reason, some installations of Vim won't allow you to backspace over text that isn't new (i.e. from before you last hit escape). To make this behaviour more logical, add the following to your .vimrc (or _vimrc on Windows):

set bs=2


How to make a backup over SSH (or, `when scp won't cut it')

scp doesn't have a --no-dereference option to stop it from following symbolic links, which makes it bad for backing up things like home directories. Instead, we can combine tar and ssh, like this:

ssh -l username remotehost 'cd parent-dir; tar -czpf - dir-to-backup' | ( cd some-dir; tar -xzvf - )
So to backup rupert's home dir on cyclops, something like this:
ssh -l rupert cyclops 'cd ../; tar -czpf - rupert' | ( cd rupertdir-backup; tar -xzvf - )


Linux 2.6 and Debian: What to do if /dev/dsp disappears after installing udev

Because udev creates all devices dynamically, you need to have the OSS support module installed in order to register /dev/dsp, /dev/mixer etc: Simply make sure you load the module snd_pcm_oss (by adding it to /etc/modules, for example).


How to do something to every file of a particular type in the filesystem

Let's say we want to list out every text file (.txt) in the whole filesystem. I used to use something like "cat *.txt; cat */*.txt; cat */*/*.txt ..." which is tedious.

First, here's how to get the name of every file:

find / -name "*.txt"
We call the program 'find', telling it to search the whole filesystem (/).

Now, we can pass this list of files to 'cat' using 'xargs'. Watch:

find / -name "*.txt" | xargs cat
'xargs' passes each word in turn to cat, and 'cat' cats that file. If your filenames might have spaces in them, you need to make sure that xargs passes whole lines rather than words; use find's option '-print0' to tell it to delimit with NULL instead of newlines, and xargs's option '-0' to tell it to use NULL instead of space as a delimiter (the order of arguments to 'find' here is important):
find / -name "*.txt" -print0 | xargs -0 cat

Other args after the variable filename?:

find / -name "*.txt" -exec myprog \{\} arg2 arg3 \;
or
find / -name "*.txt" | xargs -iFILENAME myprog FILENAME arg2 arg3


How to manipulate a file with a hyphen as the first character

Sometimes you'll have a file that starts with a hyphen ('-'). If you try to do something to it, like "less -myfile.txt", the program will think this is an option rather than a file name. Escaping the name using quotes or backslashes (or even wildcards...) doesn't work. Instead, you can do this:

less -- -myfile.txt
The '--' at the start tells the program not to treat anything else on the line as an option. This seems to work for every program.


The Netgear DG834G wireless unit's nameserver doesn't work properly

The DG834G is an ADSL modem/wireless router. It contains a nameserver which, on the unit I installed, is exceedingly flaky and unusable - it times out on most lookups and gives inconsistent answers. It apparently could be your ISP, if you'd like to look into that. A workaround is to set the unit's nameservers manually through the web interface, instead of letting it fetch them through DHCP. Then, when clients are connected to it, the nameservers they in turn receive through DHCP are your ISP's real ones instead of the local unit's IP address, and this then works properly.


Getting three mouse buttons in OSX, and pasting into X11.app

With a single-button mouse, you get three mouse buttons like this:

Middle clicks are necessary for pasting into X11 apps: While you can copy stuff out of X11 using apple-C, you can only paste into X11 using the standard X way (see apple's X11 howto).


Debian: What to do if you can't write to your cvsroot, /var/lib/cvs

Debian installs /var/lib/cvs with permissions for the group 'src' only. So add yourself to that group. As root:

# adduser yourname src


How to sync a serial Palm on an SGI IRIX machine

JPilot, the Palm-Desktop equivalent for X, is available precompiled in SGI's freeware collection. Simply change the serial port settings to use /dev/ttyfn (where n is the number of the port your palm is connected to), and 115200 bps. /dev/ttyf* is just one of the names which map to the serial ports, the f standing for "flow control" - the full list is available at microcosmos.

On my Octane, I had to use /dev/ttyf2 - /dev/ttyf1 gave the error "pi_bind: Resource busy". I don't know if this is a configuration issue on my machine though.


How to install mod_perl with apache2 on Debian Sarge

If you're getting errors like Invalid command 'PerlSetVar' when trying to use Perl content in Apache2 under Debian, you need to install mod_perl. The package to grab is libapache2-mod-perl2. Once you've installed this, you need to enable the module using the command a2enmod (no args, follow the prompts).


How to migrate a phpbb2.x database to another Debian machine running a newer version of phpbb

Very roughly:

Most of this info found here on phpbb.com.


How to make blosxom display dates in your local timezone

To get the blog package blosxom to display in your local timezone, you need to use the plugin 'timezone'. In the Debian package, this plugin is provided automatically, in /etc/blosxom/plugins/timezone. Otherwise, grab it from the plugins section of the blosxom main page and put it into the plugins directory specified in your main blosxom cgi script.

In the timezone plugin, edit the line my $blog_timezone = "EST5EDT"; to give your local timezone. For me, this was my $blog_timezone = "Australia/Sydney"; - you can probably put in whatever you find in the file /etc/timezone and it will work.


Linux boot fails with a message about unknown-block(0,0)

If your linux bootup fails with something like:

VFS: Cannot open root device "hda3" or unknown-block(0,0)
Please append a currect "root=" boot option Kernel panic:
VFS: Unable to mount root fs on unknown-block(0,0)
then triple-check that you compiled all the IDE disk related things you need into the kernel (not as modules). For me it was IDE/ATA2 support set as a module (I have a feeling this was the kernel config default!)


Indent blocks of lines in Vim

To change the indentation level of several lines of code, use the < and > keys.

For example, to indent the current line, you would type:

>>
To indent the next four lines, you could type:
4>>
And to use it in : commands, you can use it like:
:3,9>
All of these work to de-indent something as well, as in:
3<<


Modify a .deb package's dependencies by hand

I'm certain there are more automated ways to do this, but here's the basic recipe for changing a debian package's dependencies by hand.

And you should now have a working modified .deb file.


Mount a SAMBA share in your /etc/fstab (without exposing your password)

The /etc/fstab line should look like this:

//windowsserver/myshare /mnt/myshare smbfs defaults,credentials=/home/fred/.smbpasswd 0 0

The credentials file referenced in the above line will contain your username and password, and can be any name/place you like. It looks like:

username=fred
password=prettysecret
To keep it secure, don't forget to chmod it so only you and root can read it: chmod 600 .smbpasswd


Tell Vim to use a particular syntax style for all files of a certain type

Drupal uses .module files which are php files, but Vim doesn't automatically use the php syntax style. Here's a way to force it (put this in your .vimrc file):

function SetPathSyntax()
        if bufname("") =~ "module$"
                set syntax=php
        endif
endfunction
autocmd BufReadPost * call SetPathSyntax()

"module$" here is a regular expression for matching any filename ending in "module".

Adapted from here, which has some alternative approaches as well. A rather easier solution from there is:

autocmd BufRead,BufNewFile *.module set syntax=php
Note that you could match a certain directory to set a syntax on a certain path:
autocmd BufRead,BufNewFile ~/code/phpstuff/* set syntax=php


Insert newlines from a command in Vim

Imagine for example that you want to break a big paragraph into individual sentences, one per line. you want to replace occurrences of "." with ".<CTRL-M>". But typing "Control-M" simply sends an "enter" command to vim, so you must tell it an escape sequence is next by typing Control-V first. So your keystrokes will be:

:%s/\./\.<CTRL-V><CTRL-M>/g
Which will look, when you type it, like:
:%s/\./\.^M/g


Find and extract a particular file with tar

In a large .tar.gz file, you can grab particular files you want without extracting the whole thing. Say you want contacts.txt from backup.tar.gz: To find the full path of that file, do:

$ tar tzf backup.tar.gz |grep contacts.txt

The machine returns something like home/fred/docs/contacts.txt

To extract this file from the archive, you can type:

$ tar zxf backup.tar.gz home/fred/docs/contacts.txt


Scroll back in a Screen session

Screen, being ncurses-y, uses its own scrollback buffer instead of letting your terminal app do it, so scrolling normally won't work. Instead, you can tell screen to go into "copy mode" with CTRL-a ESC. Then use the arrow keys, pgup/pgdn, etc.


MozTrayBiff for linuxppc

This shouldn't be here on the hints page, but anyway - here's a precompiled MozTrayBiff for linux-powerpc, in case anyone needs it. It's compiled against ThunderBird 1.0.2: mozTrayBiff-1.1-powerpc-linux-tb1.0.2.xpi.


Connect to a mysql database using PHP from the command line ('PHP CLI')

Situation: You have a PHP script that works well for the web, but you want to run it from the command line.

You may get an error like this: Fatal error: Call to undefined function: mysql_connect(). If so, simply edit /etc/php4/cli/php.ini and uncomment the line ;extension=mysql.so.


Share a user database between Drupal and MediaWiki

I wanted to integrate a new install of MediaWiki into an existing Drupal site. The goal was to let only Drupal users make changes to the Wiki, but let everyone view it.

The (imperfect) solution involves using a cron job to copy the data from the drupal user table to the mediawiki one, and a few special settings to let MediaWiki work this way.


Telnetting to HTTP/1.1 servers cookbook

Background reading: Wikipedia: HyperText Transfer Protocol; Charles Miller: HTTP Conditional Get for RSS Hackers

Standard HTTP/1.1 request

GET /pics.html HTTP/1.1
Host: www.example.com
<enter> 

Conditional GET

The header produced by a request like the above will contain a line like Last-Modified: Mon, 15 Aug 2005 12:19:31 GMT. You can use this value in a conditional GET to request the document only if it has changed:
GET /pics.html HTTP/1.1
Host: www.example.com
If-Modified-Since: Mon, 15 Aug 2005 12:19:31 GMT
<enter> 
If the document is unmodified, you will get a response HTTP/1.1 304 Not Modified.

Instead of using the Last-Modified header, you can use the ETag - for example, you could receive the header ETag: "449e64-2d1-76971180". This is just a unique identifier for the current revision of the document you are looking at. If you cache the ETag, when you send it back using the If-None-Match header, the server will only give you the document if its ETag differs from yours (that is to say, if it has a different revision of the document):

GET /pics.html HTTP/1.1
Host: www.example.com
If-None-Match: "449e64-2d1-76971180"
<enter> 


Zero-padding numbers in Python

>>> print "%04d" % 8
0008

Where '0' is "pad with zeroes instead of spaces", and '4' is the field-width in chars. To pad with spaces, you'd use "%4d" instead.

Python seems to obey Awk-like rules for formatting - see The GNU Awk User's Guide - Format Modifiers for more details.


Getting java on Debian

Install Sun's JRE:

Tell Debian where to point /usr/bin/java to:


Stop Bash from ringing the terminal bell, make Bash use Vi keybindings

GNU Readline handles the Bash command-line; its settings are stored in ~/.inputrc. The following settings belong in there:

More here in the Bash reference manual.


How multipart html email works

There's a convention whereby when you send an HTML email, you also attach a plaintext version of the mail for other readers to display. Use this sparingly, as many 'plaintext' readers can actually hand-off HTML to an external browser conveniently; if your plaintext version is less useful than your HTML version, you may be worsening the experience for these users.

The format looks like this:

From: Sender Name <sender@example.com>
To: Recipient Name <recipient@example.com>
Subject: A simple multipart mail
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="----=_Part_aba27aebf67dca4e7e241159a76a7a3b"

------=_Part_aba27aebf67dca4e7e241159a76a7a3b
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Plaintext part goes here.

------=_Part_aba27aebf67dca4e7e241159a76a7a3b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8Bit
Content-Disposition: inline

HTML part <em>should</em> go here.

------=_Part_aba27aebf67dca4e7e241159a76a7a3b--

The boundary specified on the 5th line can be any unique string. It is then used on a line by itself, prepended by "--", to indicate the boundaries between the parts. The last part is ended by the boundary string with "--" before and after.

To generate a unique boundary string in PHP, you can use something like

$boundary = "----=_Part_" . md5(uniqid(time()))
but any unique string will do. Make sure it's unique between emails as well, otherwise some readers will assume you're quoting the text of a previous email when you send a new one.

Other notes:


How POSTing files works

Normal HTTP POST requests look like this:
POST / HTTP/1.1
Host: localhost:8000
(rest of the usual HTTP headers)
Content-Type: application/x-www-form-urlencoded
Content-Length: 20

one=first&two=second
If you want to upload a file using the form element <input type="file">, you need to add a parameter to your form:
<form method="post" action="your_cgi_script" enctype="multipart/form-data">
This instructs the browser to use a MIME-style multipart encoding for the pieces it sends to the script. If we post a file called myfile.txt, which looks like
This is my file.
This is line two.
from a form with two fields, the first a text field called 'one' and the second a file field called 'two', then the POST request looks like this:
POST / HTTP/1.1
Host: localhost:8000
(usual http headers here)
Content-Type: multipart/form-data; boundary=---------------------------27619426910078454862098207839
Content-Length: 367

-----------------------------27619426910078454862098207839
Content-Disposition: form-data; name="one"

hello
-----------------------------27619426910078454862098207839
Content-Disposition: form-data; name="two"; filename="myfile.txt"
Content-Type: text/plain

This is my file.
This is line two.

-----------------------------27619426910078454862098207839--
OK, what about posting binary files? Let's do the same experiment with a small binary file. The relevant part of the MIME message comes out like this:
ontent-Disposition: form-data; name="two"; filename="binaryfile.bin"
Content-Type: application/octet-stream
(binary gunk)
-----------------------------4086840483308214071763412686--

How to get Internet Explorer to load recalcitrant ActiveX controls

Sometimes in Internet Explorer, when you click "Install ActiveX Control" on a web page you get redirected to an earlier page instead of the control being installed. This may be because of a workaround for broken sites going wrong. To get around it, try holding down CTRL while going to the page which triggers the "Install ActiveX Control" message - it should pop up a standard dialog rather than the little top-of-the-window one, which might work better.

This happened to me when trying to visit the Dell Remote Access Controller (drac) on a server - the Media page tries to load an ActiveX control, but instead redirects to the login screen when you click to install it. The above trick fixed this for me.

Tony Schreiner's explanation (describing this fix in more detail)


Put your SSH public key on a remote server in one line

To enable passwordless logins, you have to generate a key on your workstation (ssh-keygen) and then put it in the .ssh/authorized_keys file on the target server(s). Here's how to do this without having to log in and edit/create that stuff manually on the remote machines:

ssh YOURSERVER 'mkdir -p -m0700 .ssh; cat - >> .ssh/authorized_keys' < .ssh/id_dsa.pub
(You can leave out the mkdir -p -m0700 .ssh; part unless you've never invoked SSH on the target machine before.)

If you do this a lot, you could use a script, like this:

#!/bin/sh
if [ "$1" == "" ]
	then echo "Need [user@]host"
	exit
fi
ssh $1 'mkdir -p -m0700 .ssh; cat - >> .ssh/authorized_keys' < ~/.ssh/id_dsa.pub


Log into a web-form automatically whenever your wireless interface comes up

If a wireless network you connect to requires you to log into a web page before you can use the net, you can automate it in the following fashion (specifics are for a BlueSocket-controlled network I use, but the principle should be similar for you):

Put the following script somewhere, say /home/fred/scripts/wirelesslogin.sh

#!/bin/bash
curl -s --insecure https://LOGIN-MACHINE/login.pl -d _FORM_SUBMIT=1 -d which_form=reg -d bs_name=YOURNAME -d bs_password=YOURPASSWORD > /dev/null
This script should log you into the wireless network - get it working before trying the next step.

Now you just need to have the script run when the network interface comes up. On Debian/Ubuntu, this is done by adding a script to /etc/network/if-up.d/ (this assumes your wireless interface is eth1, and that the IP range of your locked-down network is 192.*):

#!/bin/sh

if [ ! -x /home/fred/scripts/wirelesslogin.sh ]; then
        exit 0
fi

if [ "$METHOD" = loopback ]; then
        exit 0
fi

# We only want to run this for wireless logins:
if [ "$IFACE" != "eth1" ]; then
        exit 0
fi

FIRSTIPBYTE=`/sbin/ifconfig eth1 |grep "inet addr" |sed "s/.*addr://" |sed "s/\..*//"`

if [ "$FIRSTIPBYTE" = 192 ]; then
        /home/fred/scripts/wirelesslogin.sh
        logger "Running wireless login script."
else
        logger "NOT running wireless login script (detected first IP byte as $FIRSTIPBYTE)"
fi
Open question: Does this script necessarily get run when the machine wakes from ACPI sleep?


Move your root filesystem to a new partition when using UUID-based fstab

If you copy your root filesystem into a physically different partition (for example when restoring from backups), the UUID of that partition will change. If your /etc/fstab addresses partitions by UUID, you may get errors on booting like findfs: Unable to resolve 'UUID=xxxxx'. To retrieve your new UUIDs, you can run ls -l /dev/disk/by-uuid/. (the output of tune2fs -l /dev/[your partition] will also list the partition's UUID for ext2/3 partitions.) At this point you can modify the UUIDs in /etc/fstab to the new ones and reboot.


How to minimise repetition in a big, repetitive zone file (a.k.a. stupid tricks with BIND)

If you want to have a large number of mini-zones in one zone file, you can use the $ORIGIN directive to change the current context of the zonefile. For example, if your zonefile is myhouse.mystreet.mycity, your implicit origin is myhouse.mystreet.mycity.. When you specify a host, for example

kitchen  IN  A  10.0.1.1
it is inferred to be a shorthand for kitchen.myhouse.mystreet.mycity.. If you want to change the origin within part of the file, you can do something like this:
$ORIGIN myhouse.mystreet.mycity.
kitchen  IN  A  10.0.1.2  ;i.e. kitchen.myhouse.mystreet.mycity.

$ORIGIN otherhouse.mystreet.mycity.
kitchen  IN  A  10.0.2.2  ;i.e. kitchen.otherhouse.mystreet.mycity.
To specify the origin itself, you can use @ (or, I think, even an empty space):
$ORIGIN myhouse.mystreet.mycity.
@  IN  A  10.0.1.1  ;i.e. myhouse.mystreet.mycity.
If you have an identical series of CNAMEs (i.e. aliases) that you'd like to be true for multiple mini-zones, you can specify them in a separate file and use $INCLUDE. So if you make a file called mystreet.mycity-cnames:
diningroom  CNAME  kitchen  ;diningroom is an alias for kitchen
office      CNAME  study    ;office is an alias for study
and then include that file in your zonefile mystreet.mycity:
$ORIGIN myhouse.mystreet.mycity.
kitchen  IN  A  10.0.1.2
study    IN  A  10.0.1.3
$INCLUDE data/mystreet.mycity-cnames

$ORIGIN otherhouse.mystreet.mycity.
kitchen  IN  A  10.0.2.2
study    IN  A  10.0.2.3
$INCLUDE data/mystreet.mycity-cnames
then the result will be, for example, that office.myhouse.mystreet.mycity is an alias for study.myhouse.mystreet.mycity, and office.otherhouse.mystreet.mycity for study.otherhouse.mystreet.mycity.


How to edit textareas in Firefox/IceWeasel using an external editor


How to make Firefox/IceWeasel open new windows in tabs by default

This is really useful for sites that like to launch new (target="_new" or whatever) windows all the time

The values are: 1 for always open in current window, 2 for open in new window, and 3 for open in new tab. More info here.

The above seems to be the default setting in Windows Firefox, but not in the Debian/Ubuntu packages.


How to set up wifi interfaces statically using /etc/network/interfaces

For a WEP network, you could have an entry like:

auto ath0
iface ath0 inet dhcp
wireless-essid your-essid....
wireless-key abc123....
For a WPA (2?) network, something like:
auto ath0
iface ath0 inet dhcp
wpa-ssid your-essid....
wpa-passphrase your passphrase here...
(more detail from Andete)


How to specify the order of your network interfaces (eth0, eth1...)

Seems like linux has trouble assigning the same interface name (eth0, eth1...) to the same physical card each time; various solutions exist, but the newest is to use udev:

Here's an example line:
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="00:11:22:33:44:55", NAME="eth4"
I'm not entirely sure what causes the generator to re-run (and presumably destroy your changes) but the changes do survive a reboot.


How to get vmware player to wait longer at the BIOS screen

If you need to access the VMware bios settings (for example to select boot devices), the BIOS screen may disappear too quickly. To solve this, edit your .vmx file to add this line:

bios.bootDelay = "5000"
(Solution from this thread)


Testing Apache name-based virtualhosts from the command line

Often find yourself needing to test a name-based virtualhost on a non-production machine, where the names don't actually resolve to the machine you're testing? Try this handy script:

#!/bin/sh
echo "GET / HTTP/1.1
Host: $2
"| nc $1 80
eg:
getwithname.sh mytestmachine.local newfeature.mylivesite.com


Saving a file with noeol in vim

Sometimes when opening a file with vim, it says "(noeol)". If you need to save the file again without adding an EOL, do the following:

:set noeol
:set binary
...and then save.