The joy of Unix is that I'm not limited by the operating system; I'm only limited by my knowledge. To that end, I've started writing down useful shell commands, for those many times when I ask myself "How did I do that the last time I needed to?"

Afficionados of Unix should also check out UGU, the Unix Guru Universe. If you visit, I recommend signing up for their daily tip.

Use ex to remove the first line of a file:

ex -c d -c w -c q file.txt

Redirect stdout and stderr to file.txt:

somecommand.sh &> file.txt

You cannot have any space between the & and the >, or the shell will assume you want to background somecommand.sh

Remove a file that starts with a hyphen:

rm ./-rf

Find all non-CVS files that do not have "desdemona" or "app1" in their names:

find . -path '*/CVS*' -prune -or -print | grep -v desdemona | grep -v app1

Full listing of comand line in process list on Solaris:

/usr/ucb/ps -auwwwwwwwx

Halt, then power down a Sun box, extremely quickly:

/sbin/uadmin 2 6

/sbin/uadmin converts its two arguments to integers and hands them straight to the uadmin() system call. /usr/include/sys/uadmin.h defines A_SHUTDOWN 2, and AD_POWEROFF 6.

Get a public domain Korn shell for Linux:

Get the RPM for pdksh

Get the usage, in KB, of a directory and all files in it, recursively:

du -k <dirname>

Recursively remove empty directories:

rmdir `find . -type d -print`

This command takes advantage of the fact that rmdir will refuse to delete any non-empty directory. Note that you will have to run this comand a few times if, by removing one empty directory, you have left its parent empty.

Get a disk image on a floppy with dd:

dd if=boot.ig of=/dev/fd0

Note that the device for your floppy drive might conveniently be /dev/floppy

Have perl process files, backing them up with a ".bk" extension:

perl -p -i.bk -e 's/this/that/g' binky.txt

-p means process file list, -i means edit file in place, backing it up to .bk, -e means execute.

Convert DOS newlines to Unix newlines:

On Linux:

dos2unix file.txt

On Unix:

sed 's/.$//' file.txt > fixedfile.txt

Find any non-CVS file (and not directory):

find . -path '*/CVS*' -prune -or -type f -print

Find any non-CVS directory (and not file):

find . -path '*/CVS*' -prune -or -type d -print

chmod any non-CVS file:

find . -path '*/CVS*' -prune -or -type -f -exec chmod 644 {} \;

tar up non-CVS files:

tar -cvf archive.tar `find . -path '*/CVS*' -prune -or -type f -print`

Change permission on all 664 files to 664:

find . -perm 644 -exec chmod 664 {} \;

Change all CVS/Root files from one repository to another:

echo ":ext:newserver.newhost.com:/path/to/cvs/repository" > newroot
find . -path '*/CVS/Root' -exec cp newroot {} \;

Find all TODOs in a codebase (*.java files in this example):

find . -name '*.java' -exec grep -i -H -n "todo" {} \;