...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.
Get the one-line summaries from each script. Do this last.
I use lots of one-or-two-line scripts instead of aliases or shell functions because:
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.
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.
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]*
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.
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
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
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
Make a directory with decent permissions, regardless of umask.
1 #!/bin/sh 2 mkdir ${1+"$@"} && exec chmod 755 ${1+"$@"} 3 exit 1
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
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
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
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
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
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
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.
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
List anything with execute permissions.
1 #!/bin/sh 2 exec ls -laF ${1+"$@"} | fgrep "*" 3 exit 1
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.
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.
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.
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.
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
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.
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
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
In case I mangle my X-windows keyboard setup.
1 #!/bin/sh 2 test -f $HOME/.xmodmaprc && exec xmodmap $HOME/.xmodmaprc 3 exit 1
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
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
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
1 #!/bin/sh 2 exec /usr/bin/env python $HOME/lib/html2mkd.py ${1+"$@"} 3 exit 1
1 #!/bin/sh 2 exec chmod 755 ${1+"$@"} 3 exit 1
1 #!/bin/sh 2 exec /usr/local/bin/display 3 exit 1
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
1 #!/bin/sh 2 PATH=/bin:/usr/sbin:/usr/bin 3 export PATH 4 5 exec expand ${1+"$@"} | sed -e '/^ *$/d' 6 exit 1
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"
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
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
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
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
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
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
1 #!/bin/ksh 2 3 case "$#" in 4 0) ;; 5 *) exec <"$1" ;; 6 esac 7 8 align | exec sed -e 's/ //' 9 exit 1
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)
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
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
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
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
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
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
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
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
1 #!/bin/ksh 2 set X `exec /usr/bin/od -vAn -N4 -tu4 < /dev/urandom` 3 echo $2 4 exit 1
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...
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
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);
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);
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);
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);
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);
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);
Translates a file (or stdin) to lower-case.
1 #!/usr/bin/perl -w 2 print lc($_) while (<>); 3 exit(0);
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);
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.
1 #!/usr/bin/perl 2 # fix preformatted code listings to render properly. 3 4 while (<>) { 5 s/\&/\&/g; 6 s/</\</g; 7 s/>/\>/g; 8 print; 9 } 10 11 exit(0);
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);
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);
Safely renames multiple files using regular expressions.
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 }
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);
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);
Translates a file (or stdin) to upper-case.
1 #!/usr/bin/perl -w 2 print uc($_) while (<>); 3 exit(0);
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);
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);
Feel free to send comments.
Generated from article.t2t by
txt2tags
$Revision: 1.20 $
$UUID: 0b4bac8d-cce7-3f11-8e68-004dec2ca81e $