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