SHELLdorado Newsletter 2/1999 - September 5, 1999

The "SHELLdorado Newsletter" covers UNIX shell script related
topics. To subscribe to this newsletter, leave your e-mail
address at the SHELLdorado homepage:

"Heiner's SHELLdorado" is a place for UNIX shell script
programmers providing

     Many shell script examples,
     shell scripting tips & tricks + more...

 o  What's new at the SHELLdorado?
 o  Shell Tip: Korn shell build-in networking functions
 o  Shell Tip: How to execute a script for each logout
 o  Q&A: How to write a HTTP server using shell scripts

>> What's new at the SHELLdorado?

 o  New Article "Sending files as mail attachments"

    With newer mail clients (like Netscape's "Messenger") it's
    very easy to attach a file (i.e. a JPEG-image) to a mail.

    This feature would be very useful for shell scripts, too.
    Some examples:

     -	automatically send a ".tar.gz"-file for backup purposes
	to another file server

     -	automatically send multiple log files to the system
	administrator (i.e. periodically using a "cron" job),
	with each file being a mail attachment

     -	or just send the newest scanned-in holiday photos to
     	a friend

    The following article explains different ways how to send
    files as mail attachments, and gives practical examples:

>> Shell Tip: Korn shell build-in networking functions

    [ Further shell scripting tips & tricks:             ]
    [ ]

    Note: the following examples will work only with standard
    ksh implementations. They will not work with the Linux Korn
    shell "pdksh".

    Most Korn Shells (/bin/ksh) have sparsely documented, build-in
    networking functions.


	    $ date=
	    $ read date < /dev/tcp/
	    $ echo $date
	    Sun Sep  5 14:16:25 MEST 1999

    This command opens a TCP connection to the IP address
    (the local loopback IP address), and connects to the port "13"
    (daytime, see /etc/services). The current date and time is
    returned, and assigned to the variable "date".

    Note that the "/dev/tcp/*" directories do not have to exist;
    the file names are special to the Korn Shell and are interpreted
    by the shell internally. Only numerical ip addresses and port
    numbers are supported; "read date < /dev/tcp/localhost/daytime"
    does not work.

>> Shell Tip: How to execute a script for each logout

    Sometimes it's useful to execute a command after each
    logout, i.e. to cleanup temporary directories, or to log
    working hours.

    This is the way to make the shell execute the script
    $HOME/.logout after each logout:

     1. Insert this line at the beginning of the file

	    trap ". $HOME/.logout" 0

     2. Create a file named "$HOME/.logout", that may contain
	arbitrary shell commands, i.e.

	   $ cat > $HOME/.logout
	   echo "Good bye $LOGNAME, the time is `date`"

    That's it! After the next login, the shell will execute
    the contents of the file "$HOME/.logout".

    NOTE: this will not work for C-Shell dialects, i.e. TCSH

>> Q&A: How to write a HTTP server using shell scripts

    If you want to use a WWW browser like Netscape or Lynx on
    your local UNIX system for local files, you don't need a
    large HTTP server like "Apache". Sometimes the following
    small Korn shell script is sufficient to test local HTML

    The following script "httpd.ksh" implements a
    rudimentary HTTP-Server (the code is available at )

    You can test the server by first starting it ("./httpd.ksh"),
    and directing the browser to the following URL to display
    the file ".profile" from your HOME directory:

    [Note: this script  uses the non-standard "netcat"
    program available with most Linux systems, or at]

	#! /bin/ksh
	# http.ksh - minimal HTTP-Server (

	PORT=8080	# TCP port to listen to (standard is 80)
	ROOT=$HOME	# Document root. All paths are relative to this

	echo >&2 "listening to port $PORT, documentroot is $ROOT"
	while :
	    # Start "netcat" in listen mode as server. On some systems
	    # the command has# the name "nc".
	    netcat -l -p $PORT |&
	    exec 3<&p 4>&p	# redirect co-process' input to fd 3 and 4

	    # Read HTTP request header
	    while read -u3 line
	        # An empty line marks end of request header
		[[ $line = ?(\r) ]] && break
		[[ -z $requestline ]] && requestline=$line
	    # Example request line:
	    # GET /document.txt HTTP/1.0
	    echo >&2 "< REQUEST: $requestline"
	    set -- $requestline

	    # Create HTTP response header
	    [[ -d "$file" ]] && file="$file/index.html"
	    if [[ $reqtype = GET && -r $file && -f $file ]]
		print -u4 "HTTP/1.0 200 OK\r"
		print -u4 Content-Length: `wc -c < $file`"\r"
		print -u4 "\r"
		cat "$file" >&4
		print -u4 "HTTP/1.0 404 Not Found\r"
		print -u4 "\r"
	    # Close file descriptors of co-process.
	    # This should terminate it:
	    exec 3>&- 4>&-
	    # "netcat" waits for the other party to close the
	    # connection, but the browser will not do this:
	    kill -1 $! >/dev/null 2>&1

    Of course this server is very crude, but it works
    surprisingly well for the most common cases.
    Instead of listing the things the server cannot do
    (there are many), here is the definite reference for
    the things it should have been able to do: RFC 1945

If you want to comment on the newsletter, or even want to submit
an article of your own, send a mail to

To unsubscribe send a mail with the body "unsubscribe" to