[SAGE] Fwd: SHELLdorado Newsletter: 1/2002 - February 13, 2002 (fwd)

der.hans plug-discuss@lists.plug.phoenix.az.us
Tue, 19 Feb 2002 15:31:10 -0700 (MST)


moin, moin,

much of this also applies to bash.

ciao,

der.hans
-- 
#  http://home.pages.de/~lufthans/   http://www.DevelopOnline.com/
#  It's up to the reader to make the book interesting.
#  An author has only the opportunity to make it uninteresting. - der.hans

---------- Forwarded message ----------
Date: Wed, 13 Feb 2002 06:43:47 -0800 (PST)
From: David R Hartley <drhartley2002@yahoo.com>
To: Sage members <sage-members@usenix.org>
Subject: [SAGE] Fwd: SHELLdorado Newsletter: 1/2002 - February 13, 2002

This stuff is so good I just had to send it to the list.
Bon appetite!

--- Heiner Steven <heiner@stevennet.de> wrote:
> From Heiner Steven Tue Feb 12 15:59:27 2002
> Date: Wed, 13 Feb 2002 00:59:27 +0100
> From: Heiner Steven <heiner@stevennet.de>
> To: drhartley2002@yahoo.com
> Subject: SHELLdorado Newsletter: 1/2002 - February 13, 2002
>
> SHELLdorado Newsletter 1/2002 - February 13th, 2002
>
> ================================================================
> The "SHELLdorado Newsletter" covers UNIX shell script related
> topics. To subscribe to this newsletter, leave your e-mail
> address at the SHELLdorado home page:
>
> 	http://www.shelldorado.com/
>
> View previous issues at the following location:
>
> 	http://www.shelldorado.com/newsletter/
>
> "Heiner's SHELLdorado" is a place for UNIX shell script
> programmers providing
>
>      Many shell script examples,
>      shell scripting tips & tricks + more...
> ================================================================
>
> This issue focuses on Korn Shell 93
>
> Contents
>
>  o  Editorial
>  o  How to use associative arrays
>  o  How to get string lengths and sub-strings
>  o  How to create easy counting loops with the new "for" syntax
>  o  How to access variables by name using "typeset -n"
>  o  How to use the built-in printf command
>  o  Q&A: Where can I find more articles about ksh93?
>  o  Q&A: How can I write my own POP3 e-mail client using ksh?
>
> -----------------------------------------------------------------
> >> Editorial
> -----------------------------------------------------------------
>
>     Much has changed since Stephen "Steve" R. Bourne wrote his
>     command line interpreter the "Bourne Shell", or just "sh".
>     David Korn rewrote it from scratch, adding new features on
>     his way. The result, KornShell 88 (named after the year it
>     was published) is available on almost any UNIX system today.
>
>     This issue of the SHELLdorado Newsletter focuses on the
>     latest version of the KornShell: KornShell 93 (or "ksh93").
>     Many people already know and value the shell as the base of
>     the "dtksh" shell, which comes as part of the "Common
>     Desktop Environment" CDE for many UNIX systems, e.g. Solaris
>     or AIX (search for /usr/dt/bin/dtksh).
>
>     ksh93 is not only a new version of the old KornShell with
>     many new features particularly for shell script programmers:
>     it could become the new standard shell for all new UNIX
>     systems, including Linux.
>
>     The source code is now available, together with pre-compiled
>     binaries for many UNIX systems, including MacOS, Linux,
>     FreeBSD, HP-UX, AIX, Linux, Solaris, SCO UnixWare and
>     even Windows (for use with U/WIN emulation):
>
> 	http://www.research.att.com/sw/download/
>
>     If you are not interested in ksh93, you may still find the
>     small POP3 e-mail client written in "conventional" KornShell
>     (ksh88) interesting.
>
>     If you have comments or suggestions for this newsletter, or
>     even want to write an article by your own, please write me
>     an e-mail.
>
>     Heiner Steven, Editor
>     <heiner.steven@shelldorado.com>
>
>
> -----------------------------------------------------------------
> >> How to use associative arrays
> -----------------------------------------------------------------
>
>     An associative array is an array indexed by a string. This
>     lets us easily create lookup tables, e.g. a table containing
>     the full names of all users given their login id:
>
> 	typeset -A name			# "name" is an array
>
> 	# Input consists of fields separated by a colon (':')
> 	OIFS=$IFS; IFS=:
> 	while read login pw uid gid fullname ignore
> 	do
> 	     name[$login]=$fullname
> 	done < /etc/passwd
> 	IFS=$OIFS
>
> 	# $login sequentially contains all indices from name[]
> 	for login in ${!name[@]}
> 	do
> 	    print "$login: ${name[$login]}"
> 	done
>
>     This prints e.g.
>
> 	root: root
> 	nobody: nobody
> 	lp: Printing daemon
> 	heiner: Heiner Steven
> 	[...]
>
>     Within the script, print ${name[heiner]} could be used to
>     print the full name of the user with the login id "heiner".
>
>
> -----------------------------------------------------------------
> >> How to get string lengths and sub-strings
> -----------------------------------------------------------------
>
>     Some frequent string manipulations get easier with ksh93.
>     The length of each string can be printed in the following
>     way:
>
> 	a="Heiner's SHELLdorado"
>     	$ print ${#a}		# string length
> 	20
>
> 	$ print ${a:9}		# string starting with position 9
> 	SHELLdorado
>
> 	$ print ${a:9:5}	# starting with position 9; 5 characters
> 	SHELL
>
>     Even "sed" like substitutions are available.  The following
>     command replaces all "U" characters in the variable "a" with
>     an "X" in the output:
>
>     	$ print ${a//U/X}
>
>     These command make string manipulation not just easier,
>     but also much faster.
>
>
> -----------------------------------------------------------------
> >> How to create easy counting loops with the new "for" syntax
> -----------------------------------------------------------------
>
>     The old Bourne shell forced us to write code like the
>     following for simple tasks as counting from 1 to 10:
>
>     	i=1
> 	while [ $i -le 10 ]
> 	do
> 	    echo $i
> 	    i=`expr $i + 1`
> 	done
>
>     Compare this to the new ksh93 syntax:
>
>     	integer i
> 	for (( i=1; i<=10; i++ ))
> 	do
> 	    echo $i
> 	done
>
>
> -----------------------------------------------------------------
> >> How to access variables by name using "typeset -n"
> -----------------------------------------------------------------
>
>     Sometimes it's useful to specify the name of a variable as
>     an argument to a function, e.g.
>
>     	getstring firstname "First Name:"
>
>     The function "getstring" should read a string from the user,
>     and return the result in our variable "firstname". This used
>     to be solved with "eval", but ksh93 has an easier solution:
>
>     	function getstring { # varname promptstring
> 	    typeset -n vname=$1
> 	    typeset prompt=${2-"?"}
>
> 	    print -u2 "$prompt\c"
> 	    read vname
> 	}
>
>     Since "vname" contains the name of a variable (not its
>     value), all manipulations on "vname" change the value of the
>     variable specified as an argument to the function.
>
>     Without "typeset -n" we would have written the function
>     similar to the following example:
>
>     	getstring () { # varname promptstring
> 	    vname=$1
> 	    prompt=${2-"?"}
>
> 	    echo -n "$prompt" >&2
> 	    read answer
> 	    eval "$vname=\"$answer\""
> 	}
>
>
> -----------------------------------------------------------------
> >> How to use the built-in printf command
> -----------------------------------------------------------------
>
>     Why should we use yet another version of the "printf"
>     command? Many systems already have a version in /usr/bin.
>
>     Well, one advantage of printf being a built-in is, that the
>     behaviour of the function is system-independent, and ksh93
>     programmers can rely on its existence.
>
>     But this built-in version of printf is special in some other
>     ways, too:
>
>      o	If there are more arguments than formats in the format
>         string, the format string is reused. This can be used
> 	e.g. to replace "cut" in some places:
>
> 	    cut -c1,10 < /etc/passwd
>
> 	to list the first 10 characters of each line in
> 	/etc/passwd can be rewritten in the following way:
>
> 	    printf ".10s\n" /etc/passwd
>
>      o	It can convert regular expressions to shell patterns,
>      	and vice versa:
>
> 	    $ printf "%P\n" "a(b|c)x"
> 	    *a@(b|c)x*
>
> 	    $ printf "%R\n" "*a@(b|c)x*"
> 	    a(b|c)x
>
>      o	"printf" can help quoting:
>
> 	    $ printf "%q\n" "Heiner's SHELLdorado"
> 	    $'Heiner\'s SHELLdorado'
>
>     ...and printf even knows something about HTML and XML, and
>     how to expand special characters in a way suitable for HTML
>     text:
>
>     	$ printf "%H\n" "<Tips & Tricks>"
> 	&lt;Tips&nbsp;&amp;&nbsp;Tricks&gt;
>
>     Well, that does not look too readable, but we are not the
>     interpreters targeted ;-) A web browser knows how to convert
>     these "character entities" to a readable representation.
>
>
> -----------------------------------------------------------------
> >> Q&A: Where can I find more articles about ksh93?
> -----------------------------------------------------------------
>
>     The KornShell 93 is available free of charge from AT&T
>     Labs-Research:
>
>     	http://www.research.att.com/sw/download/
>
>     A concise list of the new features of ksh93 is listed
>     in the following article:
>
> 	http://www.cs.princeton.edu/~jlk/ksh93.html
>
>     The author of the shell, David Korn, maintains a web site
>     with many more articles:
>
>     	http://www.kornshell.com/
>
>     A description of the new features of ksh93 from the Linux
>     Journal:
>
>         http://www.linuxjournal.com/article.php?sid=1273
>
>     A manual page
>
>         http://www.cs.princeton.edu/~jlk/kornshell/doc/man93.html
>
>     Frequently Asked Questions (FAQ):
>
>     	http://www.kornshell.com/doc/faq.html
>
>     Many more links to shell scripts and shell scripting related
>     articles are available at the SHELLdorado Links section:
>
>     	http://www.shelldorado.com/links/
>
>
> -----------------------------------------------------------------
> >> Q&A: How can I write my own POP3 e-mail client using ksh?
> -----------------------------------------------------------------
>
>     Sometimes these viruses (like "SirCam") can really be
>     annoying. They make completely strangers send you 3 MB
>     holiday pictures, or some 5 MB audio file you did not ask
>     for. Most POP3 e-mail clients (like Netscape) will download
>     the files from the server to your local file system before
>     allowing the relieving click on the "delete" button.
>
>     In these cases the following script is useful: it can delete
>     files directly on the POP3 e-mail server, before they reach
>     the local hard disk. It can also list the e-mails, and
>     display them one by one.
>
>     The script will certainly not replace your e-mail
>     application of choice, but it may be useful for the purpose
>     stated above, or just as an example of KornShell
>     co-processes.
>
>     Note that the script does NOT require ksh93, it should run
>     with any KornShell dialect.
>
> 	#! /usr/bin/ksh
> 	# popc.ksh - example of a POP3 e-mail client written in KornShell
> 	# Heiner Steven, heiner@shelldorado.com
> 	#
> 	# This example implements the "LIST" command to list all messages,
> 	# "RETR" to retrieve a message text by number, and "DELE" to delete
> 	# a message by number.
> 	#
> 	# Refer to RFC 1939 (http://www.ietf.org/rfc/rfc1939.txt) for a full
> 	# description of the POP3 protocol.
> 	#
> 	# Needs the non-standard program "netcat" (aka "nc") to establish a
> 	# TCP connection. You could use "socket(1)" instead, if installed.
>
> 	host=localhost			# Name or address of POP3 server
> 	port=110			# POP3 port (standard is 110)
> 	user=${USER:-$LOGNAME}
> 	pass=dontsay
>
> 	typeset -u pop_status		# Global last status { "+OK" | "-ERR" }
> 	typeset pop_msg			# Global last server status message
>
> 	function Fatal { print -u2 "$@"; exit 1; }
>
> 	# sendline - send one line to co-process
>
> 	function sendline { print -p -- "$@"; }
>
> 	# getack - get positive or negative acknowledgement from server
> 	#
> 	# The server will answer with either "+OK ..." or "-ERR ...". We
> 	# evaluate the first word read from the server, and set the
> 	# return value accordingly
>
> 	function getack {
> 	    read -p -r pop_status pop_msg; print -u2 "DEBUG: $pop_status $pop_msg"
> 	    [[ $pop_status == '+OK' ]] && return 0
> 	    print -u2 -- "$pop_status $pop_msg"
> 	    return 1
> 	}
>
> 	# getlist - get multi-line response from server
> 	#
> 	# Multi-line responses are terminated by a line consisting only of
> 	#  a period '.'
>
> 	function getlist {
> 	    typeset line
>
> 	    while read -p -r line
> 	    do
> 		line=${line%+(?)}		# Remove trailing CR (ASCII 13)
> 		[[ $line == '.' ]] && break	# End of list
> 		print -- "<$line>"
> 	    done
> 	}
>
> 	function ListCmd {
> 	    sendline "LIST"
> 	    getack && getlist
> 	}
>
> 	function DeleteCmd {
> 	    integer msgno
>
> 	    read msgno?"DELETE message Number: "
> 	    sendline "DELE $msgno" && getack
> 	}
>
> 	function RetrieveCmd {
> 	    integer msgno
>
> 	    read msgno?"Retrieve message Number: "
> 	    sendline "RETR $msgno"
> 	    getack && getlist
> 	}
>
> 	# Startup the server as a co-process. We will use "print -p"
> 	# and "read -p" to write and read data.
>
> 	netcat "$host" "$port" |&	popdpid=$!
>
> 	# Check if the server is ready
> 	getack || Fatal "cannot start POP3 server $host:$port"
>
> 	# Authentication
>
> 	set -e		# First error terminates script
> 	sendline "USER $user" && getack
> 	sendline "PASS $pass" && getack
> 	set +e
>
> 	print -u2 "Authentication successful"
> 	PS3="POP3 command (RETURN prints menu): "
> 	select choice in List Retrieve Delete Quit
> 	do
> 	    case "$choice" in
> 	    (List)	ListCmd ;;
> 	    (Retrieve)	RetrieveCmd ;;
> 	    (Delete)	DeleteCmd ;;
> 	    (Quit)	break;;
> 	    esac
> 	done
>
> 	# Shut down co-process
> 	exec 3<&p 3>&p		# redirect co-process fd to fd 3
> 	exec 3<&- 3>&-		# close fd 3
> 	kill $popdpid >/dev/null 2>&1	# if the above does not work...
>
> 	exit 0
>
>     [Download location for "netcat":
> ftp://ftp.uni-stuttgart.de/pub/org/uni-s/rus/security/unix/hobbit/nc110.tgz
>
>     Check your local system first; many systems (e.g. Linux)
>     already have this program installed.
>
>     The script was tested with pdksh v5.2.14 99/07/13.2
>     (Linux) and ksh93 Version M 1993-12-28 m (Linux).]
>
>
> ----------------------------------------------------------------
>
> The examples were tested using Linux 2.4 and KornShell 93
> Version M 1993-12-28 m. Use "print ${.sh.version}" to find your
> ksh93 revision number.
>
> ----------------------------------------------------------------
> If you want to comment on the newsletter, have suggestions for
> new topics to be covered in one of the next issues, or even want
> to submit an article of your own, send an e-mail to
>
> 	mailto:heiner.steven@shelldorado.com
>
> ================================================================
> To unsubscribe send a mail with the body "unsubscribe" to
> newsletter@shelldorado.com
> ================================================================


=====
David R Hartley
drhartley2002@yahoo.com

__________________________________________________
Do You Yahoo!?
Send FREE Valentine eCards with Yahoo! Greetings!
http://greetings.yahoo.com