[ Home ]

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

Get the exit status of each command in a pipe

This works in bash. Let's say you have the following command:

zcat myfile.gz | some_other_command
The special variable $? will be the exit code of some_other_command, not zcat myfile.gz. Bash has a special array, PIPESTATUS, that has the exit commands of all commands that are piped together. To get the exit status of zcat myfile.gz, you would use ${PIPESTATUS[0]}. And the exit status of some_other_command is both $? and ${PIPESTATUS[1]}

Exit on first error

You can always check the exit code of a command and exit a shell script like this:

my_command
exit_status=$?
if [ $exit_status -ne 0 ]; then
    echo "failed with exit status $exit_status" >&2
    exit $exit_status
fi
but it's really irritating to do that after every command, so instead, at the top of your shell script, you can just say
set -e
and then your shell script will exit on the first error, and exit with the same non-zero exit code.

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

Use ex to remove the first line of a file:

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

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" {} \;