1. Introduction
  2. Summary
  3. Placeholders and aliases
  4. Managing a remote host
  5. Bourne-shell scripts
  6. Korn-shell scripts
  7. Nawk scripts
  8. Perl scripts
  9. Python scripts
  10. Feedback

1. Introduction

...in which there are a few gems buried under an enormous compost pile. Maybe you'll find something that scratches your particular itch.

The scripts actually have things like comment headers, but I stripped those for display below. The complete versions can be downloaded as individual files from each section, or as a tarball.

2. Summary

Get the one-line summaries from each script. Do this last.

3. Placeholders and aliases

I use lots of one-or-two-line scripts instead of aliases or shell functions because:

3.1. dh

Get some of the most recent entries in a directory.

 1  #!/bin/sh
 2  exec ls -lFt ${1+"$@"} | head
 3  exit 1

exec replaces the script process with ls, so if the exec fails for some reason, the script exits with 1. It's useful from a belt-and-suspenders perspective to use "exit with non-zero" any time you exec something.

3.2. dir

Your basic directory listing. I started with DEC/VMS, so I probably use this more than any other script.

 1  #!/bin/sh
 2  case "$SAVEON" in
 3      "") opt='--color=auto' ;;
 4      *)  opt='' ;;
 5  esac
 6  
 7  unset BLOCK_SIZE             # throws off the results.
 8  exec /usr/local/bin/gls -lF $opt ${1+"$@"}
 9  exit 1

I set SAVEON when I'm running script; I like listings in color, but it makes a godawful mess if I'm saving terminal output, so I turn it off.

The BLOCK_SIZE environment variable (useful with du) will definitely screw up any output from the GNU version of ls, so I kill that too.

Code: dir

3.3. dot

Same as dir, but only for dot files.

 1  #!/bin/sh
 2  
 3  case "$SAVEON" in
 4      "") opt='--color=auto' ;;
 5      *)  opt='' ;;
 6  esac
 7  
 8  unset BLOCK_SIZE             # throws off the results.
 9  exec /usr/local/bin/gls -ldF $opt .[a-zA-Z0-9]*

Code: dot

3.4. fix

Try to salvage a login session after I've trashed my terminal settings. This is one of the few aliases I use, mainly because I don't like typing "source":

 1  me% alias fix
 2  fix='source ~/.termrc.xterm'
 3  
 4  me% cat ~/.termrc.xterm
 5  # Set up terminal variables for Sun console, X-terminal.
 6  stty -tabs erase ^? kill ^U susp ^Z intr ^C eof ^D
 7  stty rows 48
 8  
 9  # TERM must be set last, or the shell gets REALLY confused.
10  export TERMINFO=/opt/sfw/share/terminfo
11  export TERM=xterm-color

It's definitely worth the time to get a decent terminfo collection, preferably the one bundled with ncurses. A good terminal setup is worth its weight in platinum just because of all the problems you'll avoid.

3.5. havepatch

Nice to have on a Solaris box if you're looking for a patch.

 1  #!/bin/sh
 2  exec showrev -p | grep "^Patch: ${1+"$@"}"
 3  exit 1

3.6. isodate

Prints an ISO-standard date. I used this as part of a map command in VI before VIM came along.

 1  #!/bin/sh
 2  exec date '+%Y-%m-%d %H:%M:%S'
 3  exit 1

3.7. look, spell

This does a lookup or spell-check using a better dictionary. Look:

 1  #!/bin/sh
 2  exec /usr/local/bin/look ${1+"$@"} /usr/local/share/dict/single.txt
 3  exit 1

Spell:

 1  #!/bin/sh
 2  exec /bin/spell +/usr/local/share/dict/single.txt ${1+"$@"}
 3  exit 1

3.8. mk

Make a directory with decent permissions, regardless of umask.

 1  #!/bin/sh
 2  mkdir ${1+"$@"} && exec chmod 755 ${1+"$@"}
 3  exit 1

3.9. p

Sometimes you never know where someone'll stick less. Not to mention it's too many characters to type.

 1  #!/bin/sh
 2  exec /usr/local/bin/less ${1+"$@"}
 3  exit 1

3.10. packages

I use FreeBSD a lot, and I like a quick path to the prebuilt stuff. If you've never given ncftp a try, you should.

 1  #!/bin/sh
 2  exec ncftp ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-7.2-release/
 3  exit 1

3.11. r, ro

Makes a file read/write or readonly for the owner. I don't like messing with umask.

 1  #!/bin/sh
 2  exec chmod 644 ${1+"$@"}     # use 444 for ro
 3  exit 1

3.12. screenshot

Takes a screenshot of your X desktop and leaves it in screendump.png. Requires import from ImageMagick.

 1  #!/bin/sh
 2  exec /usr/local/bin/import $HOME/prn/screendump.png
 3  exit 1

3.13. se

Runs emacs without any X-windows stuff. I use qmail as my MTA, and this also sets up my environment for sending mail from within emacs.

 1  #!/bin/sh
 2  unset DISPLAY
 3  EMAIL=${QMAILUSER}@${QMAILHOST}; export EMAIL
 4  exec /usr/local/bin/emacs ${1+"$@"}
 5  exit 1

3.14. tl

Display 64-bit timestamps.

 1  #!/bin/sh
 2  case "$#" in
 3      0) ;;
 4      *) exec <"$1" ;;
 5  esac
 6  
 7  exec /usr/local/bin/tai64nlocal
 8  exit 1

If you use Dan Bernstein's code, you'll run into microsecond-precision timestamps looking like this:

@400000004aff7135028364fc sent 12441 57
@400000004aff713502b24114 sent 12442 49
@400000004aff713502c2f284 sent 12443 67

His tai64nlocal program reads stdin and translates:

2009-11-14 22:10:35.042165 sent 12441 57
2009-11-14 22:10:35.045236 sent 12442 49
2009-11-14 22:10:35.046330 sent 12443 67

3.15. tr0

Replaces newlines with nulls.

 1  #!/bin/sh
 2  PATH=/bin:/usr/bin; export PATH
 3  exec tr '\012' '\000'
 4  exit 1

This comes in handy when I need to send some poorly-chosen filenames to another program via xargs -0.

3.16. traceroute

Lots of firewalls block UDP stuff, so this has traceroute use ICMP ECHO instead.

 1  #!/bin/sh
 2  exec /usr/sbin/traceroute -I ${1+"$@"}
 3  exit 1

3.17. x

List anything with execute permissions.

 1  #!/bin/sh
 2  exec ls -laF ${1+"$@"} | fgrep "*"
 3  exit 1

4. Managing a remote host

I do this so often that it's worth a section by itself. If I have a server to take care of, I'll always need to login, get files, or deposit files. Here's the skeleton of a script I use for each server:

 1  #!/bin/ksh
 2  # connect to example.com, get a file, or put a file.
 3  
 4  PATH=/usr/local/bin:/bin:/sbin:/usr/bin
 5  export PATH
 6  tag=${0##*/}
 7  
 8  cipher="-c arcfour"
 9  host=example.com
10  ident="-i $HOME/.ssh/examplecom_dsa"
11  
12  connect () { exec ssh $cipher $ident $host; exit 1; }
13  usage ()   { echo "usage: $tag [get|put file]"; exit 1; }
14  
15  case "$#" in
16      0) connect ;;
17      2) action=$1; file=$2 ;;
18      *) usage ;;
19  esac
20  
21  set -x
22  case "$action" in
23      get) exec scp $cipher $ident $host:$file .    ;;
24      put) exec scp $cipher $ident $file $host:/tmp ;;
25  esac
26  
27  exit 1

I usually make the script name the same as the server hostname, so to connect to example.com, I'd just type example.com.

To copy something to /tmp on the server: example.com put somefile. Line 8 specifies the arcfour cipher, which is quite a bit faster than the rest.

To get a file from the server: example.com get /path/to/somefile.

If I stand up a new server, the only lines I need to change are the ones setting the hostname (line 9) and the SSH key used to connect (line 10). I turn debug output on at line 21 so I can see the commands used for copying files, in case something screws up.

Code: example.com

5. Bourne-shell scripts

5.1. addmail

Safely add a file (or stdin) to my mailbox.

 1  #!/bin/sh
 2  PATH=/bin:/usr/bin:/usr/local/bin:/opt/sfw/bin
 3  export PATH
 4  lockfile -ml && cat $1 >> $MAIL && exec lockfile -mu
 5  exit 1

This assumes you have the procmail package installed. lockfile will either lock your main mailbox or return a fail code and force an immediate exit. After that, append either the first argument or stdin to your mailbox and unlock it.

Code: addmail

5.2. bytes

Displays the total number of bytes for one or more files.

 1  #!/bin/sh
 2  PATH=/bin:/usr/bin
 3  export PATH
 4  exec ls -l $* | awk 'BEGIN {sum = 0} {sum += $5} END {print sum}'
 5  exit 1

This reads the output from ls and sums the "size" column.

5.3. codewords

Neat way to estimate the complexity of a given C header or program file, taken from a Dan Bernstein paper on secure coding.

 1  #!/bin/sh
 2  cat $* \
 3    | cpp -fpreprocessed \
 4    | sed 's/[_a-zA-Z0-9][_a-zA-Z0-9]*/x/g' \
 5    | tr -d ' \012' \
 6    | wc -c
 7  exit 0

Suppose you want to measure the complexity of your basic "Hello, World" program:

me% cat hello.c
/*
 * This is a comment.  We love comments.
 */

#include <stdio.h>
#define BINDIR "/usr/ccs/bin"

main()
{
    printf("hello, world\n");
    printf("bin directory is %s\n", BINDIR);

#ifdef unix
    printf("unix defined\n");
#endif

/* coredump!
    abort ();
*/
    exit(0);
}

me% codewords hello.c
65

Here's the step-by-step. Run hello.c through cpp (line 3)...

# 5 "<stdin>"
#include <stdio.h>


main()
{
    printf("hello, world\n");
    printf("bin directory is %s\n", BINDIR);

#ifdef unix
    printf("unix defined\n");
#endif


    exit(0);
}

...use sed (line 4) to replace any function, variable name, or reserved word with an x...

# x "<x>"
#x <x.x>


x()
{
    x("x, x\x");
    x("x x x %x\x", x);

#x x
    x("x x\x");
#x


    x(x);
}

...use tr (line 5) to kill spaces and newlines...

#x"<x>"#x<x.x>x(){x("x,x\x");x("xxx%x\x",x);#xxx("xx\x");#xx(x);}

...and count the remaining characters (line 6).

65

You now have a decent estimate of how many words requiring some thought are in your code. Way better than LOC.

Code: codewords

5.4. dict

Does a quick dictionary lookup.

 1  #!/bin/sh
 2  PATH=/bin:/usr/bin:/usr/local/bin:/opt/sfw/bin; export PATH
 3  
 4  case "$#" in
 5      0) echo "Need a word"; exit 1 ;;
 6      *) u='http://www.m-w.com/cgi-bin/dictionary?book=Dictionary&va='"$*" ;;
 7  esac
 8  
 9  exec lynx -width=80 -dump "$u" |
10      sed -n -e '/entry found/,/Learn more about/p' |
11      tr '\267' '-'
12  exit 1

Code: dict

5.5. dnlc

Prints some kernel variables plus directory/inode cache statistics for Solaris 8-10. Unfortunately, it suffers from integer overflow if your host is at all busy; you'll get negative percentages, etc.

On a smaller Solaris workstation, you'll get something like this:

Directory/inode cache statistics
(See /usr/include/sys/dnlc.h for more information)

maxphys:          57344    Max physical request
ufs_ninode:      524288    Inode cache size
sq_max_size:      10000    Streams queue
ncsize:          524288    Directory name cache size
nrnode:          191573    nrnode
ncstats:     1095585404    # of cache hits that we used
ncstats+4:    439492417    # of misses
ncstats+8:    440025509    # of enters done
ncstats+0xc:      94734    # of enters tried when already cached
ncstats+0x10:         0    # of long names tried to enter
ncstats+0x14:         0    # of long name tried to look up
ncstats+0x18:   1438571    # of times LRU list was empty
ncstats+0x1c:      9659    # of purges of cache
                     71    Hit rate percentage

If your percentage is under 90, you could probably use more memory.

Code: dnlc

5.6. dtree

Code: dtree

5.7. dupfiles

Code: dupfiles

5.8. errno

Code: errno

5.9. f1-f9

This reads stdin and prints a specific whitespace-delimited field, which comes in handy more often than you'd think.

 1  #!/bin/sh
 2  PATH=/bin:/usr/bin; export PATH
 3  tag=`basename $0`
 4  
 5  case "$tag" in
 6      f1) exec awk '{print $1}' ;;
 7      f2) exec awk '{print $2}' ;;
 8      f3) exec awk '{print $3}' ;;
 9      f4) exec awk '{print $4}' ;;
10      f5) exec awk '{print $5}' ;;
11      f6) exec awk '{print $6}' ;;
12      f7) exec awk '{print $7}' ;;
13      f8) exec awk '{print $8}' ;;
14      f9) exec awk '{print $9}' ;;
15      *)  ;;
16  esac
17  
18  exit 1

It's a script with 9 hard-links, and it behaves differently depending on the name used to invoke it:

me% ls -lF f?
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f1*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f2*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f3*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f4*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f5*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f6*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f7*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f8*
-rwxr-xr-x 9 bin bin 550 Nov 13 21:20 f9*

me% ls -lF k*
-rwxr-xr-x 1 bin bin 2915 Feb  5  2002 keep*
-rwxr-xr-x 1 bin bin  473 Jan  3  2008 kill-ads*
-rwxr-xr-x 1 bin bin  472 Jul 23 21:12 killdups*
-rwxr-xr-x 1 bin bin 4662 Jul 28 12:48 killpg*
-rwxr-xr-x 1 bin bin 7817 Jun 27  2008 kwic*

me% ls -lF k* | f5
2915
473
472
4662
7817

Code: f1

5.10. fixbullet

 1  #!/bin/sh
 2  PATH=/bin:/usr/bin; export PATH
 3  sed -e 's/\*/  */' | fmt -1 | fmt -75 | exec sed -e 's/  \*/*/'
 4  exit 1

Code: fixbullet

5.11. fixkbd

In case I mangle my X-windows keyboard setup.

 1  #!/bin/sh
 2  test -f $HOME/.xmodmaprc && exec xmodmap $HOME/.xmodmaprc
 3  exit 1

5.12. fmt

 1  #!/bin/sh
 2  case "$FMTWIDTH" in
 3      "") opt= ;;
 4      *)  opt="-$FMTWIDTH" ;;
 5  esac
 6  
 7  case "$1" in
 8      -*) opt= ;;
 9      *)  ;;
10  esac
11  
12  exec /usr/local/bin/gfmt $opt ${1+"$@"}
13  exit 1

Code: fmt

5.13. ftp

In case you want to run a specific version of FTP for a given host, or use a given set of arguments.

 1  #!/bin/sh
 2  prog=/usr/bin/ftp
 3  
 4  case "$1" in
 5      "")        exec $prog ;;
 6      server1)   ;;
 7      server2)   ;;
 8      *)         prog=/usr/local/bin/ncftp ;;
 9  esac
10  
11  exec $prog ${1+"$@"}
12  exit 1

5.14. gt, gthuge, gtgiant

Short for gnome-terminal. I have three terminal setups; small, medium, and large text. This script handles all three depending on what name is used to invoke it.

I use the "Bitstream Vera Sans Mono" font on a Dell 19" monitor; it's very readable if your eyesight sucks.

The small text setting (profile "Local") displays 49 lines of 80-column text using fontsize 12.

The medium text setting (profile "Huge") displays 41 lines of 80-column text using fontsize 14.

The large text setting (profile "Giant") displays 37 lines of 80-column text using fontsize 16.

 1  #!/bin/sh
 2  
 3  PATH=/bin:/usr/bin:/usr/openwin/bin:/usr/local/bin; export PATH
 4  h=unix
 5  DISPLAY="$h:0.0"; export DISPLAY
 6  
 7  # fix keyboard.
 8  test -f $HOME/.xmodmaprc && xmodmap $HOME/.xmodmaprc &
 9  test -f $HOME/.Xdefaults && xrdb -merge $HOME/.Xdefaults &
10  
11  # Start GNOME terminal on the right; using "+0+0" is for the left side.
12  case "`basename $0`" in
13      gt)      pro=Local; geom='--geometry=80x49-0+0' ;;
14      gthuge)  pro=Huge;  geom='--geometry=80x41-0+0' ;;
15      gtgiant) pro=Giant; geom='--geometry=80x37-0+0' ;;
16  esac
17  
18  exec gnome-terminal --window-with-profile=$pro $geom &
19  exit 1

Code: gt

5.15. gvi

Code: gvi

5.16. hdr

Code: hdr

5.17. html2mkd

 1  #!/bin/sh
 2  exec /usr/bin/env python $HOME/lib/html2mkd.py ${1+"$@"}
 3  exit 1

Code: html2mkd

5.18. ifdef

Code: ifdef

5.19. incfile

Code: incfile

5.20. ipurl

Code: ipurl

5.21. mcrypt

Code: mcrypt

5.22. mdecrypt

Code: mdecrypt

5.23. mergemail

Code: mergemail

5.24. mf

Code: mf

5.25. mgrep

Code: mgrep

5.26. mh

Code: mh

5.27. msort

Code: msort

5.28. mx

 1  #!/bin/sh
 2  exec chmod 755 ${1+"$@"}
 3  exit 1

Code: mx

5.29. mypaint

 1  #!/bin/sh
 2  exec /usr/local/bin/display
 3  exit 1

Code: mypaint

5.30. nextuid

 1  #!/bin/sh
 2  cut -f3 -d: /etc/passwd |
 3      sort -n |
 4      awk 'BEGIN { prev = 0 }
 5      {
 6          np = prev + 1
 7          if ($1 > 100 && $1 != np) {
 8              print np
 9  	    exit
10          }
11          prev = $1
12      }'
13  
14  exit 0

Code: nextuid

5.31. noblank

 1  #!/bin/sh
 2  PATH=/bin:/usr/sbin:/usr/bin
 3  export PATH
 4  
 5  exec expand ${1+"$@"} | sed -e '/^ *$/d'
 6  exit 1

Code: noblank

5.32. nr

Code: nr

5.33. prioritymail

Code: prioritymail

5.34. prndd

Code: prndd

5.35. pvi

Code: pvi

5.36. pwgen

Code: pwgen

5.37. range

Code: range

5.38. rename-mail

Code: rename-mail

5.39. rptnew

Code: rptnew

5.40. sparcinfo

Prints the hardware setup for a Solaris box; mostly just a driver for the system printdiag command. Here's the output for my workstation:

me% sparcinfo
sparcinfo  v1.1  2001/04/21 22:50:10

Output from /usr/platform/i86pc/sbin/prtdiag -v:

    System Configuration:
      Dell Computer Corporation OptiPlex GX260
    BIOS Configuration: Dell Computer Corporation A03 09/24/2002

    ==== Processor Sockets ====================================

    Version                          Location Tag
    -------------------------------- --------------------------
    Pentium 4                        Microprocessor

    ==== Memory Device Sockets ================================

    Type    Status Set Device Locator      Bank Locator
    ------- ------ --- ------------------- --------------------
    SDRAM   in use 0   DIMM_A
    SDRAM   in use 0   DIMM_B

    ==== On-Board Devices =====================================
    Intel 845G PCI Accelerated SVGA
    Intel Pro 1000 MT Network Connection
    AC'97 Audio Controller

    ==== Upgradeable Slots ====================================

    ID  Status    Type             Description
    --- --------- ---------------- ----------------------------
    1   available PCI              PCI1
    2   available PCI              PCI2
    3   available PCI              PCI3
    4   available PCI              PCI4
    0   in use    AGP 4X           AGP1

The first output line is the RCS version and date, without all the dollar-sign-keyword crap. Here's an easy way to do that:

lsedscr='s/RCSfile: //
s/.Date: //
s/,v . .Revision: /  v/
s/\$//g'

lrevno='$RCSfile: article.t2t,v $ $Revision: 1.20 $'
lrevdate='$Date: 2010/01/05 20:01:19 $'
echo "$lrevno $lrevdate" | sed -e "$lsedscr"

Code: sparcinfo

5.41. ss

Save the current X-windows screen as a JPEG screenshot. Requires convert from ImageMagick.

 1  #!/bin/sh
 2  case "$#" in
 3      0) name=image ;;
 4      *) name="$1" ;;
 5  esac
 6  
 7  exec /usr/local/bin/convert X: jpeg:$name.jpg
 8  exit 1

Code: ss

5.42. sunman

Run man using only Solaris manpages.

 1  #!/bin/sh
 2  MANPATH=/usr/man:/usr/openwin/share/man:/usr/sfw/man:/opt/sfw/man
 3  export MANPATH
 4  exec man ${1+"$@"}
 5  exit 1

5.43. sysname

This tries to guess a canonical system name. It's just a copy of the GNU config.guess script from the Xapian search-engine distribution.

me% sysname
i386-pc-solaris2.10

Code: sysname

5.44. tardir

Code: tardir

5.45. texi2man

Code: texi2man

5.46. truss.obsd

 1  #!/bin/sh
 2  PATH=/usr/local/bin:/bin:/usr/sbin:/usr/bin
 3  export PATH
 4  
 5  case "$#" in
 6      0)  echo "usage: $0 prog"; exit 1 ;;
 7      *)  ;;
 8  esac
 9  
10  tmp=`mktemp /tmp/tfile.XXXXXXXXXX`
11  case "$?" in
12      0)  ;;
13      *)  echo mktemp failed; exit 1 ;;
14  esac
15  
16  ktrace -f $tmp -t ceinsw ${1+"$@"}
17  kdump -ndR -f $tmp
18  rm $tmp
19  exit 0

Code: truss.obsd

5.47. tstmsg

 1  #!/bin/sh
 2  
 3  case "$#" in
 4      0) echo 'no destination'; exit 1 ;;
 5      *) dest=$1 ;;
 6  esac
 7  
 8  incfile=$HOME/.tstmsg
 9  
10  test -f $incfile || echo 0 > $incfile
11  test -f $incfile || exit 1
12  k=`cat $incfile`
13  k=`expr $k + 1`
14  echo $k > $incfile
15  
16  now=`date "+%Y-%m-%d %T"`
17  sub="Test msg $k at $now"
18  echo "Test msg $k" | mail -s "$sub" $dest
19  
20  exit 0

Code: tstmsg

5.48. uidl

Code: uidl

5.49. xnote

Code: xnote

5.50. xt

Code: xt

5.51. zp

Shortcut to run less on a file, compressed or otherwise.

 1  #!/bin/sh
 2  PATH=/usr/local/bin:/bin:/usr/bin; export PATH
 3  
 4  case "$#" in
 5      0)  exit 1 ;;
 6      *)  file="$1" ;;
 7  esac
 8  
 9  case "$file" in
10      *.gz)   exec gunzip -c "$file"     | less ;;
11      *.bz2)  exec bunzip2 -c "$file"    | less ;;
12      *.Z)    exec uncompress -c "$file" | less ;;
13      *)      exec less $file ;;
14  esac
15  
16  exit 1

Code: zp

6. Korn-shell scripts

6.1. actkm

Code: actkm

6.2. agenda

Code: agenda

6.3. als

 1  #!/bin/ksh
 2  
 3  case "$#" in
 4      0) ;;
 5      *) exec <"$1" ;;
 6  esac
 7  
 8  align | exec sed -e 's/               //'
 9  exit 1

Code: als

6.4. core

This prints a stack trace for a coredump. Here's the version for systems using the "adb" debugger. It expects the name of a corefile as an argument:

 1  #!/bin/ksh
 2  PATH=/bin:/usr/bin; export PATH
 3  
 4  case "$1" in
 5      "") exit 1 ;;
 6      *)  echo '$c' | exec /bin/adb $* ;;
 7  esac
 8  
 9  exit 1

Here's the version for systems using the "gdb" debugger. It expects the name of a corefile or a program as an argument; the corefile is named "program.core".

 1  #!/bin/ksh
 2  PATH=/bin:/usr/bin; export PATH
 3  
 4  case "$1" in
 5      "")     exit 1 ;;
 6      *.core) f=$(basename $1 | sed -e 's/.core$//') ;;
 7      *)      f=$(basename "$1") ;;
 8  esac
 9  
10  echo 'bt' | exec gdb $f $f.core
11  exit 1

For example, I got the program "man2html" to dump when translating a manpage into HTML:

me% file /usr/local/man/man1/core
/usr/local/man/man1/core: ELF 32-bit LSB core file Intel 80386, version 1
  (SYSV), SVR4-style, from 'man2html perltoc.1'

me% core /usr/local/man/man1/core
core file = /usr/local/man/man1/core -- program ``/usr/local/bin/man2html''
  on platform i86pc
SIGSEGV: Segmentation Fault
expand_string+0x26(80e7b42, d0fd066a, d0ed6d44, d0ed6d44, 8046778, 0)
scan_troff+0x133(8072c21, 0, 0, 80589e3)
main+0x2fa(2, 8046a58, 8046a64)
_start+0x80(2, 8046c94, 8046c9d, 0, 8046ca7, 8046cc1)

Code: core

6.5. cppdef

Code: cppdef

6.6. cshar

Code: cshar

6.7. curl

 1  #!/bin/ksh
 2  prog=/usr/local/bin/curl
 3  proxy=1.2.3.4:5678
 4  
 5  case "$#" in
 6      0) exec less /doc/html/htdocs/curlhelp.txt ;;
 7      *) exec $prog -x $proxy ${1+"$@"} ;;
 8  esac
 9  exit 1

Code: curl

6.8. f

Code: f

6.9. faxcover

Code: faxcover

6.10. ffdump

Code: ffdump

6.11. fixlog

Code: fixlog

6.12. g

 1  #!/bin/ksh
 2  PATH=/usr/local/bin:/bin:/usr/bin; export PATH
 3  
 4  case "$#" in
 5      0) set $LOGNAME ;;
 6      *) set X $(( for name; do grep -i $name /etc/passwd; done ) |
 7                cut -f1 -d: | sort -u) ; shift ;;
 8  esac
 9  
10  case "$#" in
11      0) echo "Sorry, could not find any of those names"; exit 1 ;;
12      *) exec groups $@ ;;
13  esac
14  exit 1

Code: g

6.13. getperm, setperm

 1  #!/bin/ksh
 2  # get permissions for use with setperm script.
 3  # usage: getperm /tmp
 4  #        getperm -type f .
 5  
 6  PATH=/bin:/usr/bin:/usr/local/bin
 7  export PATH
 8  
 9  case "$#" in
10      0)  echo "usage: $0 dir"; exit 1 ;;
11      *)  ;;
12  esac
13  
14  exec gfind ${1+"$@"} -printf "%u %g %m %p\n" | sort +3 -t' '
15  exit 0

Code: getperm

 1  #!/bin/ksh
 2  # set permissions based on input lines.
 3  # sample permissions file entry:
 4  #   owner    group    mode  path
 5  #   outgoing outgoing 775   /other/outgoing
 6  
 7  PATH=/bin:/usr/bin:/usr/local/bin
 8  export PATH
 9  
10  awk '{
11    print "chown", $1, $4
12    print "chgrp", $2, $4
13    print "chmod", $3, $4
14  }' $1
15  
16  exit 0

Code: setperm

6.14. getquote

 1  #!/bin/ksh
 2  PATH=/usr/local/bin:/usr/bin:/bin
 3  export PATH
 4  qfile="$HOME/.quotes.cdb"
 5  
 6  max=$(cdbget 0 < $qfile)
 7  r=$(random 1 1 $max)
 8  exec cdbget $r < $qfile
 9  exit 1

Code: getquote

6.15. google

Code: google

6.16. got

Code: got

6.17. host

Code: host

6.18. html2txt

 1  #!/bin/ksh
 2  # run w3m to get a well-formatted text version of an HTML file.
 3  
 4  prog='/usr/local/bin/w3m -dump -T text/html'
 5  
 6  case "$#" in
 7      0) $prog ;;
 8      *) $prog < $1 ;;
 9  esac
10  
11  exit 0

Code: html2txt

6.19. keep

Code: keep

6.20. kill-ads

Code: kill-ads

6.21. l

Code: l

6.22. lsd

Code: lsd

6.23. mkdist

Code: mkdist

6.24. mkmail

Code: mkmail

6.25. mkman

Code: mkman

6.26. mkproto

Code: mkproto

6.27. mkshar

Code: mkshar

6.28. month

Code: month

6.29. mtree

Code: mtree

6.30. newvers, vers

newvers creates a well-behaved version tag (i.e., "x.y") by abusing the hell out of RCS. This comes in handy when:

It's easy; write the process id and a random number to a file called .version in the current directory, check it in, and read the resulting RCS file. No arguments means print the incremented version number. A numeric argument changes the primary version. For example:

me% vers
no version file

me% newvers
1.1

me% newvers
1.2

me% newvers
1.3

me% newvers a
2.1

me% newvers
2.2

me% newvers 9
9.1

me% newvers
9.2

me% vers
9.2

Here's the code:

 1  #!/bin/ksh
 2  PATH=/bin:/usr/bin:/usr/local/bin
 3  export PATH
 4  file=.version
 5  
 6  showme () {
 7      # Keep the RCS file in the current directory - cleaner.
 8      test -f RCS/${file},v && mv RCS/${file},v .
 9  
10      set X $(head -1 ${file},v | tr ';.' '  ')
11      case "$#" in
12          4) echo $3.$4 ;;
13          *) ;;
14      esac
15  }
16  
17  # We don't care what goes in as long as it changes.
18  echo $$.$RANDOM > $file
19  
20  case "$#" in
21      0)  echo checkin | ci -q ${file}        # minor version
22          rcs -q -U ${file}
23          showme
24          ;;
25  
26      *)  arg="$1"
27          if test -f ${file},v; then          # major version
28              set X $(head -1 ${file},v | tr ';.' '  ')
29              major=$(($3 + 1))
30          else
31              major=1
32          fi
33  
34          # We have an argument, is it numeric?
35          expr "$arg" : "[0-9]*$" > /dev/null && major=$arg
36  
37          echo checkin | ci -r${major}.1 -q ${file}
38          rcs -q -U ${file}
39          showme
40          ;;
41  esac
42  
43  exit 0

Code: newvers

vers prints the current version number, if any.

 1  #!/bin/ksh
 2  PATH=/bin:/usr/bin:/usr/local/bin
 3  export PATH
 4  file=.version
 5  rc=0
 6  
 7  # Why get rid of the period and then add it back?  It makes the tr
 8  # commands completely consistent between newvers and vers.
 9  
10  if test -f ${file},v; then
11      set X $(head -1 ${file},v | tr ';.' '  ')
12      case "$#" in
13          4) echo $3.$4 ;;
14          *) echo "${file},v is not an RCS file" >& 2; rc=1 ;;
15      esac
16  else
17      echo "no version file" >& 2
18      rc=2
19  fi
20  
21  exit $rc

Code: vers

6.31. nl

Code: nl

6.32. pidof

Code: pidof

6.33. postexten

Code: postexten

6.34. rand

 1  #!/bin/ksh
 2  set X `exec /usr/bin/od -vAn -N4 -tu4 < /dev/urandom`
 3  echo $2
 4  exit 1

Code: rand

6.35. rcsd

Code: rcsd

6.36. recover

Code: recover

6.37. rem

Code: rem

6.38. runmail

Code: runmail

6.39. shellscript-l

Code: shellscript-l

6.40. skill

Code: skill

6.41. sman

Code: sman

6.42. srch

Code: srch

6.43. tc

Code: tc

6.44. tcv

Code: tcv

6.45. tx

 1  #!/bin/ksh
 2  case "$#" in
 3      0)  echo need a file; exit 0 ;;
 4      *)  file="$1"; pat="$2" ;;
 5  esac
 6  
 7  case "$file" in
 8      *.tgz)    exec gunzip     -c "$file" | tar xvf - $pat ;;
 9      *.bz2)    exec bunzip2    -c "$file" | tar xvf - $pat ;;
10      *.tbz)    exec bunzip2    -c "$file" | tar xvf - $pat ;;
11      *.pax.gz) exec gunzip     -c "$file" | pax -rd -pe $pat ;;
12      *.tar.gz) exec gunzip     -c "$file" | tar xvf - $pat ;;
13      *.tar.Z)  exec uncompress -c "$file" | tar xvf - $pat ;;
14      *.zip)    exec unzip -a "$file" ;;
15      *)        exec tar xvf $file $pat ;;
16  esac
17  
18  exit 1     # should not get this far...

Code: tx

6.46. update-feed

Code: update-feed

6.47. updated

Code: updated

6.48. w3m

Code: w3m

6.49. wndex

Code: wndex

6.50. xinit

 1  #!/bin/ksh
 2  # start X with authority, assuming XDM is not running.
 3  
 4  PATH=/usr/local/bin:/bin:/sbin:/usr/sbin:/usr/bin:/usr/X11R6/bin
 5  XAUTHORITY=$HOME/.Xauthority
 6  #LD_LIBRARY_PATH=/usr/X11R6/lib:/usr/lib:/usr/local/lib
 7  export PATH XAUTHORITY
 8  
 9  # generate random key; length must be even or xauth complains
10  randomkey=$(echo $(( $RANDOM * $RANDOM * 2 )) | md5)
11  xauth add $(hostname)/unix:0 . $randomkey
12  xauth add $(hostname):0 . $randomkey
13  
14  # start X with authority
15  exec xinit $HOME/.xinitrc -- /usr/X11R6/bin/X -auth $HOME/.Xauthority
16  exit 0

Code: xinit

7. Nawk scripts

7.1. primes

Code: primes

8. Perl scripts

8.1. abbreviate

Code: abbreviate

8.2. add

Code: add

8.3. aline

Code: aline

8.4. avg

Code: avg

8.5. b64

Code: b64

8.6. babyl2mbox

Code: babyl2mbox

8.7. backslash

 1  #!/usr/bin/perl -w
 2  # backslash: remove trailing backslash characters
 3  # based on "Pro Perl" backslash.pl (p195)
 4  
 5  use strict;
 6  
 7  while (<>) {
 8      chomp;
 9  
10      if (s/\\$//) {            # trailing backslash?
11          my $line = <>;
12          $_ .= $line, redo;    # goes to the 'chomp' above
13      }
14  
15      print "$_\n";
16  }
17  
18  exit(0);

Code: backslash

8.8. bclinks

Code: bclinks

8.9. blog

Code: blog

8.10. blood

Code: blood

8.11. bsdsec

Code: bsdsec

8.12. buildenv

Code: buildenv

8.13. burst-python

Code: burst-python

8.14. capitalize

Code: capitalize

8.15. caps

Code: caps

8.16. cgrep

Code: cgrep

8.17. change

Code: change

8.18. cline

Code: cline

8.19. cm

Code: cm

8.20. commflags

Code: commflags

8.21. cssalign

Code: cssalign

8.22. dbinfo

Code: dbinfo

8.23. dehyph

 1  #!/usr/bin/perl -w
 2  
 3  use strict;
 4  $/ = "";    # Enable paragraph mode.
 5  $* = 1;     # Enable multi-line patterns.
 6  
 7  while (<>) {
 8      s/-\n\s*//g;    # Dehyphenate hyphenations.
 9      print;
10  }
11  
12  exit(0);

Code: dehyph

8.24. dir2htm

Code: dir2htm

8.25. dirdiff

Code: dirdiff

8.26. dline

Code: dline

8.27. due2rem

Code: due2rem

8.28. dups.pl

Code: dups.pl

8.29. emaddr

Code: emaddr

8.30. email-wrap

Code: email-wrap

8.31. enprint

Code: enprint

8.32. eztable

Code: eztable

8.33. fetchurl

Code: fetchurl

8.34. ffhistory

Code: ffhistory

8.35. fftoday

Code: fftoday

8.36. file2hash

Code: file2hash

8.37. file2log

Code: file2log

8.38. filter-exch

Code: filter-exch

8.39. find-largest-mail

Code: find-largest-mail

8.40. find8

 1  #!/usr/bin/perl -w
 2  # highlight lines having characters with 8th bit on.
 3  
 4  use strict;
 5  my ($pfx, $str);
 6  
 7  while (<>) {
 8      $str = $_;
 9      $pfx = '  ';
10      $pfx = '* ' if tr [\200-\377] [\000-\177];
11      print "$pfx $str";
12  }
13  
14  exit(0);

Code: find8

8.41. findfrom

Code: findfrom

8.42. fixdate

Code: fixdate

8.43. fixfrom

Code: fixfrom

8.44. fixqm

Code: fixqm

8.45. fixspell

Code: fixspell

8.46. flags

Code: flags

8.47. fmtbase

Code: fmtbase

8.48. fmtlynx

Code: fmtlynx

8.49. formail2file

Code: formail2file

8.50. ftype

Code: ftype

8.51. getdate

Code: getdate

8.52. haval

Code: haval

8.53. href

 1  #!/usr/bin/perl -w
 2  
 3  use strict;
 4  my $match;
 5  
 6  while (<>) {
 7      chomp;
 8  
 9      if (/href=\"(.*)\"/i) {
10          $match = $1;
11          $match =~ s/ .*$//g;
12          $match =~ s/\"//g;
13          print "$match\n";
14      }
15  }
16  
17  exit(0);

Code: href

8.54. htls

Code: htls

8.55. html2words

Code: html2words

8.56. htmlcal

Code: htmlcal

8.57. htmldiff

Code: htmldiff

8.58. htmltoc

Code: htmltoc

8.59. htmlvars

Code: htmlvars

8.60. idxcache2html

Code: idxcache2html

8.61. img2toc

Code: img2toc

8.62. isdir

 1  #!/usr/bin/perl
 2  # print only directories from a list of files.
 3  
 4  while (<>) {
 5      chomp;
 6      print "$_\n" if -d "$_";
 7  }
 8  exit(0);

Code: isdir

8.63. isreg

 1  #!/usr/bin/perl
 2  # print only regular files from a list of files.
 3  
 4  while (<>) {
 5      chomp;
 6      print "$_\n" if -f "$_";
 7  }
 8  exit(0);

Code: isreg

8.64. killdups

Code: killdups

8.65. killpg

Code: killpg

8.66. kwic

Code: kwic

8.67. lc

Translates a file (or stdin) to lower-case.

 1  #!/usr/bin/perl -w
 2  print lc($_) while (<>);
 3  exit(0);

8.68. linkdups

Code: linkdups

8.69. log2art

Code: log2art

8.70. log2blog

Code: log2blog

8.71. log2html

Code: log2html

8.72. log2html.old

Code: log2html.old

8.73. log2troff

Code: log2troff

8.74. longest

Code: longest

8.75. ls2htm

Code: ls2htm

8.76. ls2sitemap

Code: ls2sitemap

8.77. lwp-request

Code: lwp-request

8.78. maildates

Code: maildates

8.79. mailenvecho

Code: mailenvecho

8.80. markdown

Code: markdown

8.81. mb

Code: mb

8.82. mb2md

Code: mb2md

8.83. md5path

 1  #!/usr/bin/perl -w
 2  # print relatively random filename.
 3  
 4  use strict;
 5  use Digest::MD5 qw(md5_hex);
 6  $|++;
 7  
 8  my $file = md5_hex(md5_hex(time . {} . $< . $( . rand() . $$));
 9  print "$file\n";
10  exit (0);

Code: md5path

8.84. metaphone

Code: metaphone

8.85. metaphone2

Code: metaphone2

8.86. mktitle

Code: mktitle

8.87. mlage

Code: mlage

8.88. mozilla-history

Code: mozilla-history

8.89. mp

Code: mp

8.90. msend

Code: msend

8.91. mtime

Code: mtime

8.92. munpack

Code: munpack

8.93. mv2inode

Code: mv2inode

8.94. mvlog2dir

Code: mvlog2dir

8.95. ncat

Code: ncat

8.96. new

Code: new

8.97. newfiles

Code: newfiles

8.98. newpost

Code: newpost

8.99. nid

Code: nid

8.100. notags

Strips HTML tags, character entities and other garbage from files. This script gets the award for having the most hideous regular expression I've ever seen.

Code: notags

8.101. numgroups

Code: numgroups

8.102. numpara

Code: numpara

8.103. opera-history

Code: opera-history

8.104. path2sig

Code: path2sig

8.105. path2uri

Code: path2uri

8.106. pathinfo

Code: pathinfo

8.107. ped

Code: ped

8.108. perlgrep

Code: perlgrep

8.109. pg

Code: pg

8.110. pgnews

Code: pgnews

8.111. pr2troff

Code: pr2troff

8.112. pre2html

 1  #!/usr/bin/perl
 2  # fix preformatted code listings to render properly.
 3  
 4  while (<>) {
 5      s/\&/\&amp;/g;
 6      s/</\&lt;/g;
 7      s/>/\&gt;/g;
 8      print;
 9  }
10  
11  exit(0);

Code: pre2html

8.113. print-file

Code: print-file

8.114. print-mail

Code: print-mail

8.115. ptouch

Code: ptouch

8.116. pwran

Code: pwran

8.117. qmLogsort

Code: qmLogsort

8.118. randomkey

 1  #!/usr/bin/perl
 2  # print a decent random string for .Xauthority
 3  
 4  use strict;
 5  use FileHandle;
 6  
 7  my ($foo, $seed);
 8  
 9  # Read our seed from /dev/urandom
10  my $urandom = new FileHandle "</dev/urandom";
11  die "can't open /dev/urandom" unless $urandom;
12  
13  for (1..4) {
14      sysread($urandom, $foo, 4);
15      $seed = unpack("L", $foo);
16      printf("%8.8x", $seed);
17  }
18  
19  printf("\n");
20  $urandom->close;
21  exit(0);

Code: randomkey

8.119. randomline

 1  #!/usr/bin/perl
 2  # From: Edward Vielmetti
 3  # Date: Thu, 5 May 2005 14:46:56 -0400
 4  # Subject: [43F Group] Re: shuffle theory of management
 5  # randomline: print a random line
 6  
 7  srand;
 8  rand($.) < 1 && ($line = $_) while <>;
 9  # $line is the random line
10  print $line;
11  exit (0);

Code: randomline

8.120. randstring

Code: randstring

8.121. rename

Safely renames multiple files using regular expressions.

Code: rename

8.122. rev

Code: rev

8.123. rl

 1  #!/usr/bin/perl -w
 2  use strict;
 3  
 4  if (@ARGV) { show($_) foreach (@ARGV); }
 5  else       { show($_) while (<>); }
 6  exit(0);
 7  
 8  sub show {
 9      chomp(my $file = shift);
10      if (-l $file) { print "$file: ", readlink($file), "\n"; }
11      else          { print "$file: NOT a symlink\n"; }
12  }

Code: rl

8.124. rptls

Code: rptls

8.125. ruler

Code: ruler

8.126. safeinc

Code: safeinc

8.127. saveps

Code: saveps

8.128. sdbm

Code: sdbm

8.129. sdelf

Code: sdelf

8.130. sen

 1  #!/usr/bin/perl
 2  # find end of sentences, add newlines.
 3  
 4  while (<>) {
 5      chomp;
 6      s/\s*$//g;
 7      print "$_\n";
 8      print "\n" if /[\.\)!\?\"]$/;
 9  }
10  
11  exit(0);

Code: sen

8.131. setgroup

Code: setgroup

8.132. shaname

Code: shaname

8.133. showhdr

Code: showhdr

8.134. site2html

Code: site2html

8.135. snapshot

Code: snapshot

8.136. sort-logfile

Code: sort-logfile

8.137. sortbydate

Code: sortbydate

8.138. spcheck

Code: spcheck

8.139. split-babyl

Code: split-babyl

8.140. stat

Code: stat

8.141. storepid

Code: storepid

8.142. t2html

Code: t2html

8.143. text2doc

Code: text2doc

8.144. th

Code: th

8.145. timediff

Code: timediff

8.146. timefile

Code: timefile

8.147. tip2html

Code: tip2html

8.148. tree2excel

Code: tree2excel

8.149. ts2html

Code: ts2html

8.150. txt2word

 1  #!/usr/bin/perl
 2  # read plain text, write something for import into Word.
 3  
 4  $/ = "";    # paragraph mode.
 5  
 6  while (<>) {
 7      s/-\n+\s+//g;          # no hyphenated lines.
 8      s/\n/ /g;              # no newlines.
 9      print "$_\r\n\r\n";    # print a paragraph ending with CR-LF.
10  }
11  
12  exit(0);

Code: txt2word

8.151. uc

Translates a file (or stdin) to upper-case.

 1  #!/usr/bin/perl -w
 2  print uc($_) while (<>);
 3  exit(0);

8.152. uri2path

Code: uri2path

8.153. url

Code: url

8.154. uuid

Code: uuid

8.155. vmstat

 1  #!/usr/bin/perl -w
 2  # reformat output from vmstat
 3  
 4  use strict;
 5  open(my $fh, "/bin/vmstat -s |") || die "vmstat";
 6  
 7  while (<$fh>) {
 8      chomp;
 9      s/^\s\s*//;
10      my ($first, @rest) = split;
11      printf "%10s ", $first;
12      print "@rest\n";
13  }
14  
15  close($fh);
16  exit(0);

Code: vmstat

8.156. whichmod

Code: whichmod

8.157. wnmake

Code: wnmake

8.158. wntitle

Code: wntitle

8.159. wnuncache

Code: wnuncache

8.160. wraplines

Code: wraplines

8.161. xmlcook

Code: xmlcook

8.162. xmlpp

Code: xmlpp

8.163. xmlread

Code: xmlread

8.164. xmltext

Code: xmltext

8.165. zap8bit

 1  #!/usr/bin/perl
 2  # replace 8-bit characters with spaces.
 3  
 4  while (<>) {
 5      tr/\000-\177/ /cs;
 6      print;
 7  }
 8  exit(0);

Code: zap8bit

9. Python scripts

9.1. html2text.py

Code: html2text.py

9.2. markup.py

Code: markup.py

9.3. ns

Code: ns

9.4. rgrep

Code: rgrep

10. Feedback

Feel free to send comments.


Generated from article.t2t by txt2tags
$Revision: 1.20 $
$UUID: 0b4bac8d-cce7-3f11-8e68-004dec2ca81e $