(hit 'NEXT', 'PREVIOUS' to move between slides)
Probably obsolete list
| function | korn | bash |
| simple output | echo | |
| discipline functions | yes | no |
| POSIX character classes | yes | no |
| help | no | yes |
| 'cd' spelling correction | no | yes |
| arithmetic (C-style) for | yes | no |
| arithmetic bases | 2-36 | 2-64 |
| array initialization | set -A USERVAR value1 .... | USERVAR=(value1 ....) |
| array size | limited | unlimited |
| associative arrays | yes | no |
| compond arrays | yes | no |
history file vrs. byte tokens
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
# <- the comment indicator
trap "" 2 3
# This was suggested by a note in Linux Journal
# to make it harder to stop the execution of this script
# trap = internal shell command to set response to signals
# "..." = 'double quoted' string literal, contains commands to run
# 2 3 = SIGINT SIGQUIT signals, run kill -l for complete list
PATH="/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games"
# PATH = Search path for commands
if [ "$BASH" ]; then
# if <command> Basic ALGOL derived selection structure
# then
# .....
# elif <command>
# then
# .....
# else
# .....
# fi "
#
# [...] = synonymn for the test command
# "..." = 'double quoted' string literal,
# with variable interpolation
# $ = variable 'expansion' - access the value
# BASH = pathname of the running instance of bash,
# one of several miscellaneous shell status variables
# typically '/bin/bash'
# ; = command seperator
PS1='\u@\h:\w\$ '
# PS1 = basic command line prompt
# \u = user name
# \h = host name up to first '.'
# \w = current working directory
# \$ = If the effective UID is 0 print #, otherwise print $
else
# run this branch if not BASH shell
if [ "`id -u`" -eq 0 ]; then
# `...` = command substitution operators
# capture the output into a variable,
# replacing end of lines with blanks
PS1='# '
# '...' = string literal with no interpolation
else
PS1='$ '
fi
fi
export PATH PS1
# export = move these variables/values into the 'environment'
# they can now be inherited by child processes
umask 022
# umask = sets file permissions turned off by default when file created
alias ls='/bin/ls -lF '
alias w3m='/usr/bin/w3m -F -M '
# alias = defines a shorthand label for a command
# trailing blank allows alias to follow alias on command line
export ls w3m
# From Tansley, page 190
case $LOGNAME in
# case $variable in ALGOL derived selection structure
# pattern1 )
# ;;
# pattern2 )
# ;;
# ....
# * )
# esac
dallas )
;;
* )
PID=${$}; export PID
# '$' = Process ID shell variable
# Original in Tansley:
# Connected=$( who | awk '{print $1}' | fgrep -xc ${LOGNAME} )
# $(...) synonymn for `....`
Connected=` who | awk '{print $1}' | fgrep -xc ${LOGNAME} `
# -- modified for Bourne/sh compatibility
if [ "$Connected" -gt 1 ]
then
echo
echo 'You are logged in more than once.'
echo
who -u | grep $LOGNAME
echo
echo 'Enter <CR> to exit \c'
read FRED
kill -1 $PID
exit
# Note that Bash uses 'echo' for most output, not ksh style 'print'
fi
;;
esac
# End of Tansley
###########################################################
# runsocks:
###########################################################
# This part was originally a seperate command for
# 'tricking' normal network client commands to
# run as 'SOCKSified' through SOCKS proxy servers.
# (for use with LAFN.org)
# By incorporating it here, it allowed the commands
# to be run transparently, without having to
# prefix every invocation with 'runsocks'.
# A similar approach might be used for other
# library version compatability problems.
#
# Was typically run by:
# runsocks lynx http://...
# !/bin/sh
#
# Put the path to the socks shared library in our LD_LIBRARY_PATH so when we
# preload the library, ld.so will find it...
#
if test -n "${SOCKS5_SHLIB_RUNPATH}" ; then
SOCKS5_SHLIB_RUNPATH="${SOCKS5_SHLIB_RUNPATH}/"
elif test -n "/usr/lib"; then
SOCKS5_SHLIB_RUNPATH="/usr/lib/"
else
SOCKS5_SHLIB_RUNPATH="./"
fi
#
# Some OS's use PRELOADS=lib while others use _RLD_LIST=lib:DEFAULT. Hopefully
# this can handle all those cases. At any rate, this is basically causing the
# socks5 shared libary to be used to resolve symbols before other libraries,
# hence we get socks's connect before we get libc's connect...
#
# Also, on SunOS 4*, LD_LIBRARY_PATH has no effect on, so we need to put the path
# in front of it. We make the path overridable with SOCKS5_SHLIB_RUNPATH...
#
case `uname -rs` in
SunOS*4.*)
LD_PRELOAD=${SOCKS5_SHLIB_RUNPATH}libsocks5_sh.so
export LD_PRELOAD
;;
*)
if test -z "$LD_LIBRARY_PATH" ; then
LD_LIBRARY_PATH=${SOCKS5_SHLIB_RUNPATH}
else
LD_LIBRARY_PATH=${SOCKS5_SHLIB_RUNPATH}:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
fi
LD_PRELOAD=libsocks5_sh.so
export LD_LIBRARY_PATH
;;
esac
#
# Run the actual program...
#
export LD_PRELOAD
# exec "$@"
# This last point is not needed by incorporating these
# steps in this command.
# End of RunSOCKS
trap 2 3
# Resetting signal response to defaults
# ~/.bash_profile: executed by bash(1) for login shells. umask 002 # umask set the default permissions turned off with file creation echo in .bash_profile # ~/.profile: executed by bash(1) for login shells if .bash_profile # not present. if [ -f ~/.bashrc ]; then source ~/.bashrc # 'source' reads and executes commands in file as if typed in # it does not create another shell process # synonymn for more cryptic '.' # Some languages use '#include', 'load' etc. fi # original: PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin PATH=/usr/local/bin:/usr/bin:/bin export PATH CDPATH=/usr/local:~/: export CDPATH # CDPATH variable, similar to the PATH variable, but it # provides directories where the 'cd' command # searches if it does not immediately find the # directory to switch to. mesg n # mesg allow/disallow various chat programs to write to terminal # below d.e.l. customizations: set -o vi # Setting vi style command editing LOCKPRG=/usr/bin/lockvc /usr/bin/screen -wipe # First, clean up the sockets used by screen # sometimes they may be in a confused state, not assigning # pseudo terminals in the appropriate order. exec /usr/bin/screen -d -RR # And finally reconnect to any lost sessions # putting screen in place as my 'meta-shell'
# ~/.bashrc: executed by bash(1) for non-login shells.
CDPATH=/usr/local/:/usr/loca/bin:~/:.:
# export CDPATH -- d.e.l. export apparently not needed
# special shell variables.
HISTIGNORE=' *:&'
# do not log in the history (file) commands with leading spaces,
# or duplicates of previous commands
# Set up some variables to identify what console is in use:
VCI=$(tty)
export VCI
VC=${VCI#?*/}
# Note: '#?*/' part of variable expansion strips out
# leading parts of variable to the first '/'
export VC
# end of console variable setting
# Now include in one in the prompt:
export PS1="\n\e[7m\e[24;1H \d | \@ | \h | $VC | \u | \s | \! | \# |\
\e[0m\n\
\w \$ "
# PS1 / Main prompt special sequences used:
# \n = newline escape
# \e = the escape character (^[ / C-[ / Cntl-[)
# \e[7m = go to reverse video (ANSI escape sequence)
# \e[24;1H = move cursor to line 24, row 1 (ANSI escape sequence)
# \d = date
# \@ = time in 12 hour am/pm format
# \h = host name up to first '.'
# $VC = tty console name (see above)
# \u = current user name
# \s = name of the shell (bash :-) )
# \! = history number of current command
# \# = command number of the current command
# \e[0m = restore normal video (ANSI escape sequence)
# \w = the current working directory
# \$ = if effective uid=0,'#', otherwise literal '$'
# -- See O'Reilly bash book, 2nd edition p. 71-72 for complete list.
# PROMPT_COMMAND='echo -n ^[[0J'
PROMPT_COMMAND=''
umask 022
set -o vi
# SHOPT settings, defualts unless otherwise stated ************************
# NOTE: 'ad:' == 'apparent default:'
#
# ad: shopt -u cdable_vars
shopt -s cdable_vars
# These variables require no leading '$' for interpretation, so
# this adds greatly to the capability of the 'cd' command
# allowing simple '<variable>=<dir>' definitions to make quick shortcuts
# ad: shopt -u cdspell
shopt -s cdspell
# -- This checks, and corrects for slop in directory spelling.
# ad: shopt -u checkhash
shopt -s checkhash
# -- this shouldn't cause any problem, and might speed things up,
# so why not?
# it provides a sticky-bit like feature for shell functions
# ad: shopt -u checkwinsize
shopt -s checkwinsize
# -- Keep COLUMNS and LINES updated, seems a good idea when splitting
# the screen with 'screen'.
shopt -s cmdhist
# -- bash attempts to save all lines of
# a multiple-line command in the same history entry.
# This allows easy re-editing of multi-line commands.
# ad: shopt -u dotglob
shopt -s dotglob
# -- Look at *all* the files by default.
# including those hidden with leading '.' in name
# ad: shopt -u execfail
shopt -s execfail
# so exec will not cause failure
# apparent default: shopt -u expand_aliases
shopt -s expand_aliases
# to expand aliases in scripts
# ad: shopt -u extglob
shopt -s extglob
# -- to enable *(...), +(...), @(...), ?(...), !(...) patterns
shopt -u histreedit
shopt -u histappend
shopt -u histverify
shopt -s hostcomplete
shopt -u huponexit
shopt -s interactive_comments
shopt -u lithist
shopt -u mailwarn
shopt -u nocaseglob
shopt -u nullglob
shopt -s promptvars
shopt -u restricted_shell
shopt -u shift_verbose
shopt -s sourcepath
# END of SHOPT settings ****************************************
export HISTFILESIZE=1000
# Start Aliases **********************************************************
# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval `dircolors`
# alias ls='ls $LS_OPTIONS'
# alias ll='ls $LS_OPTIONS -l'
# alias l='ls $LS_OPTIONS -lA'
#
# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'
# From 'The UNIX Companion' p. 187
alias a='alias'
# From 'The UNIX Companion' p. 641 -642
a ls='ls -F'
a ll='ls -l'
a la='ls -a'
a lla='ls -la'
# because this seems very usefull to me,
a reference='lynx /var/cache/www/refdesk.html'
a refdesk='lynx /var/cache/www/refdesk.html'
a m-w='lynx /var/cache/www/m-w.html'
# cd ~/download ; lynx -source http://www.refdesk.com > refdesk.html
# quoting and escaping is critical on this (both of these worked):
alias base642txt="perl -MMIME::Base64 -pe '\$_=decode_base64(\$_)'"
alias lynx='/usr/bin/lynx -image_links '
# End Aliases **********************************************************
# Start Functions **********************************************************
cdcleanup () {
if [[ 0 != $? ]]
then
POSSDIR=${_##*;}
# $_ = last argument to previous command
# '##*;' strips out maximum length leading string that includes
# a trainling ';' command seperator
if [[ -n ${POSSDIR} ]]
then
echo "Changing to directory: ${POSSDIR}" 2> /dev/null
cd ${POSSDIR} 2> /dev/null
fi
fi
# Possibly put some other function calls etc. here....
}
PROMPT_COMMAND=cdcleanup
# -- to execute function cdcleanup automaticly
# it may be necessary to nest other function calls inside
# cdcleanup if further automatic execution fuctionality
# is needed.
# End Functions **********************************************************
export LANG=C
export FTP_PASSIVE=1
# to make Net::FTP work behind my ipchains/packet filtering firewall
# To make sure lynx works properly:
ln -sf ~/.lynxrc.works ~/.lynxrc
(Thanks to the wonders of 'screen')
Sun May 5 | 08:16pm | dxmcgyver | pts/5 | dallas | bash | 900 | 17 | ~/download $ Sun May 5 | 08:16pm | dxmcgyver | pts/5 | dallas | bash | 900 | 17 | ~/download $ Sun May 5 | 08:16pm | dxmcgyver | pts/5 | dallas | bash | 900 | 17 | ~/download $ Sun May 5 | 08:16pm | dxmcgyver | pts/5 | dallas | bash | 900 | 17 | ~/download $ Sun May 5 | 08:16pm | dxmcgyver | pts/5 | dallas | bash | 900 | 17 | ~/download $ Sun May 5 | 08:16pm | dxmcgyver | pts/5 | dallas | bash | 900 | 17 | ~/download $ ls my*.txt my0102a.txt my0302a.txt my0402a.txt my0502a.txt myaddr1.txt my0102b.txt my0302b.txt my0402b.txt my0502b.txt mysug1.txt my0202a.txt my0302c.txt my0402c.txt myaddr.txt Sun May 5 | 08:17pm | dxmcgyver | pts/5 | dallas | bash | 901 | 18 | ~/download $ _
I really don't have any example here, but it is available. It might be used to cleanup temporary files or personal recording of session time.
Suggested by O'Reilly bash book:
| CTRL-A | Start of line |
| CTRL-E | End of line |
| CTRL-F | Forward one character |
| CTRL-B | Backward one character |
| CTRL-D/DEL | Delete one character |
| CTRL-K | Kill line |
| CTRL-P | Previous command in history |
| CTRL-N | Next command in history |
| CTRL-R | Search for command in history |
| CTRL-I/TAB | File name completion |
| \C- | Control key prefix |
| \M- | Escape/Meta key prefix |
| \e | Escape character |
| \\ | \ |
| \" | " |
| \' | ' |
# /etc/inputrc - global inputrc for libreadline # See readline(3readline) and `info readline' for more information. # Be 8 bit clean. set input-meta on set output-meta on # To allow the use of 8bit-characters like the german umlauts, comment out # the line below. However this makes the meta key not work as a meta key, # which is annoying to those which don't need to type in 8-bit characters. # set convert-meta off # Start D.E.L. customizations: $if bash $if mode=vi # from 'Learning the Bash Shell', 1rst ed., p. 58 set keymap vi-command Control-a: beginning-of-line Control-e: end-of-line Control-f: forward-char Control-b: backward-char Control-d: delete-char # Control-c: reverse-search-history Control-c: kill-whole-line Control-p: previous-history Control-n: next-history Control-r: reverse-search-history # TAB: reverse-search-history TAB: complete set keymap vi-insert # These basic emacs motions/commands don't seem to conflict # with vi insert mode, so why not? Control-a: beginning-of-line Control-e: end-of-line Control-f: forward-char Control-b: backward-char Control-d: delete-char # Control-c: reverse-search-history # Control-c: kill-whole-line Control-p: previous-history Control-n: next-history Control-r: reverse-search-history # TAB: complete $endif $endif # End of D.E.L. customizations:
variable=value
export somevariable
| \ | single following character quoted |
| '...' | string literal, no interpolation |
| "..." | string literal, interpolates |
| `...` -> should be using $(...) | command output to string, interpolates |
| $(< file ) | file contents into a string |
| $((...arithmetic...)) | creates a number string |
| number literals: |
|
if [ ..globbing test.. ] # required
then # required
...
elif [[ ..pattern test.. ]]
then
...
elif (( ..math test.. )) ; then
# ------ a common idiom
...
else
...
fi # required
case variable in
pattern1 ) ....
;; # == 'break'
pattern2 ) ....
# ;; -- now fall through to pattern3
pattern3 | pattern4 ) ....
;;
* ) .... # 'else/otherwise'
......
esac
Excerpted from an e-mail script.
case $KMHIST1 in
# Take care of network specifier dollar 1
#
# print 'A - Usenet (via alpha.jpunix.com)'
'A' | 'a' )
# KMPREFIX='INT:M2N\45\V(NDATE)\45'
KMPREFIX=${form}'M2N\45\V(NDATE)\45'
# REM \V(NDATE) IS A KERMIT TIME/DATE VARIABLE THAT
# REM PRODUCES THE YYYYMMDD REQUIRED BY
# REM THIS TYPE OF MAIL TO NEWS GATEWAYS
KMPOSTFIX='@ALPHA.JPUNIX.COM'
KADDR="$1"
shift
;;
# print 'B - Usenet (nospam via alpha.jpunix.com)'
'B' | 'b' )
# KMPREFIX='INT:M2N_NOSPAM\45\V(NDATE)\45'
KMPREFIX=${form}'M2N_NOSPAM\45\V(NDATE)\45'
# REM \V(NDATE) IS A KERMIT TIME/DATE VARIABLE THAT
# REM PRODUCES THE YYYYMMDD REQUIRED BY
# REM THIS TYPE OF MAIL TO NEWS GATEWAYS
KMPOSTFIX='@ALPHA.JPUNIX.COM'
KADDR="$1"
shift
;;
# print 'D - distribution list'
'D' | 'd' )
KMPREFIX=''
KADDR="$1"
shift
;;
# print 'F - forum'
'F' | 'f' | '\' )
KMPREFIX='\'
KADDR="$1"
shift
;;
# print 'I - Internet (U.S.A./Canada/United Kingdom/Germany)'
'I' | 'i' | 'INT:' )
# KMPREFIX='INT:'
KMPREFIX=${form}
# REM CHECK NOW FOR A COMMON ADDRESS ERROR:
case $1 in
?*@?* ) : ; ;;
* ) noatsign $1 ; return 13 ; ;;
esac
case ${1##*.} in
[Cc][Oo][Mm] ) : ;;
[Gg][Oo][Vv] ) : ;;
[Ee][Dd][Uu] ) : ;;
[Oo][Rr][Gg] ) : ;;
[Nn][Ee][Tt] ) : ;;
[Mm][Ii][Ll] ) : ;;
[Uu][Ss] ) : ;;
[Cc][Aa] ) : ;;
[Uu][Kk] ) : ;;
[Dd][Ee] ) : ;;
[Nn][Ll] ) : ;;
* )
print
print -r " %2, Which you gave as the Internet address,"
print -r " \i\s not valid - it does not have a valid domain."
print
kmdereg 13
return 13
;;
esac
KADDR="$1"
shift
;;
##################################################
# print 'J - Internet (Rest of the World)'
'J' | 'j' | 'INT:' )
# KMPREFIX='INT:'
KMPREFIX=${form}
# REM CHECK NOW FOR A COMMON ADDRESS ERROR:
case $1 in
?*@?* ) : ;;
* ) noatsign $1 ; return 13 ;;
esac
case $1 in
*[.]* ) : ;;
* ) print
print -r " $1, Which you gave as the Internet address,"
print -r " is not valid - it does not have a '.'"
print
kmdereg 13
return 13
;;
esac
KADDR="$1"
shift
;;
# print 'L - local'
'L' | 'l' )
KMPREFIX=''
KADDR="$1"
shift
;;
# print 'M - Major Net'
'M' | 'm' | 'ML:' )
KMPREFIX='ML:'
KADDR="$1"
shift
;;
# print 'N - FAXinet ###10DigitFAX###+Full_Name'
'N' | 'n' )
# KMPREFIX='INT:'
KMPREFIX=${form}
# REM ###10DIGITFAX###+Full_Name
# REM _ = SPACE
# REM CHECK NOW FOR A COMMON ADDRESS ERROR:
# REM * ECHO %2 | FIND "+" > %SCRATCH%:\FQTEST.TMP
case $1 in
*[+]* ) : ;;
* ) print
print 'Not a valid Faxinet address... '
print
kmdreg
esac
case ${1##*[+]} in
[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ) : ;;
* ) print
print -r 'Not a valid Faxinet 10 digit number'
print
kmdereg 13
return 13
;;
esac
KMPOSTFIX='+5111@FAX.AWA.COM'
KADDR="$1"
shift
;;
# print 'P - FidoNet Zone:Net/Node.Point'
'p' | 'P' )
# KMPREFIX="INT:${1}@"
KMPREFIX="${form}${1}@"
shift
zonenet=${1%%/[0-9.]*}
zone=${zonenet%%:[0-9]*}
net=${zonenet##[0-9]*:}
fnodepoint=${1##[0-9:]*/}
fnode=${fnodepoint%%.[0-9]*}
point=${fnodepoint##[0-9]*.}
for i in $zone $net $fnode $point
do
case $i in
[0-9]* ) : ;;
* ) print
print 'Improper FidoNet address'
print
return 13
;;
esac
done
KADDR=p${point}.f${fnode}.n${net}.z${zone}
KMPOSTFIX='.fidonet.org'
unset -v zonenet
unset -v zone
unset -v net
unset -v nodepoint
unset -v node
unset -v point
shift
# for testing
print $KMPREFIX
print $KADDR
print $KMPOSTFIX
exit # to test
;;
# print 'T - TPC FAX gateway Full_Name/Rm_###@###11DigitFAX###'
'T' | 't' )
# KMPREFIX='INT:remote-printer.'
KMPREFIX=${form}'remote-printer.'
# REM FULL_NAME@###11DigitFAX####
# REM _ = SPACE, /=NEWLINE IN USERNAME (suggested for Rm. #
# REM CHECK NOW FOR A COMMON ADDRESS ERROR:
case $1 in
?*@?* ) : ;;
* ) noatsign $1 ; return 13 ;;
esac
case ${1##*@} in
1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ) : ;;
* ) print
print -r 'Not a valid TPC 11 digit number'
print
kmdereg 13
return 13
;;
esac
KMPOSTFIX='.iddd.tpc.int'
KADDR="$1"
shift
;;
###############################
# print 'U - Usenet (via MIT)'
'U' | 'u' )
# KMPREFIX='INT:MAIL2NEWS\45\V(NDATE)\45'
KMPREFIX=${form}'MAIL2NEWS\45\V(NDATE)\45'
# REM \V(NDATE) IS A KERMIT TIME/DATE VARIABLE THAT
# REM PRODUCES THE YYYYMMDD REQUIRED BY
# REM THIS TYPE OF MAIL TO NEWS GATEWAYS
KMPOSTFIX='@ANON.LCS.MIT.EDU'
;;
# print 'V - Usenet (nospam via MIT)'
'V' | 'v' )
# KMPREFIX='INT:MAIL2NEWS_NOSPAM\45\V(NDATE)\45'
KMPREFIX=${form}'MAIL2NEWS_NOSPAM\45\V(NDATE)\45'
# REM \V(NDATE) IS A KERMIT TIME/DATE VARIABLE THAT
# REM PRODUCES THE YYYYMMDD REQUIRED BY
# REM THIS TYPE OF MAIL TO NEWS GATEWAYS
KMPOSTFIX='@ANON.LCS.MIT.EDU'
KADDR="$1"
shift
;;
# print 'W - World Link'
'W' | 'w' | 'WL:' )
KMPREFIX='WL:'
KADDR="$1"
shift
;;
# print 'X - Faxaway Full_Name.###11DigitFAX###'
'X' | 'x' )
# KMPREFIX='INT:'
KMPREFIX=${form}
# REM FULL_NAME.###11DigitFAX###
# REM _ = SPACE
# REM CHECK NOW FOR A COMMON ADDRESS ERROR:
case $1 in
*1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ) : ;;
* ) print
print -r 'Not a valid Faxaway 11 digit number'
print
kmdereg 13
return 13
;;
esac
KMPOSTFIX='@FAXAWAY.COM'
KADDR="$1"
shift
;;
# print 'Z - Usenet (via ZIPPO)'
'Z' | 'z' )
# KMPREFIX='INT:POST\45'
KMPREFIX=${form}'POST\45'
# REM Another mail to Usenet gateway.
KMPOSTFIX='@NEWSPOST.ZIPPO.COM'
;;
# GOTO NONET
* ) print
# :NONET
print -r 'You failed to specify a Network:'
print
kmnetlist
return
KADDR="$1"
shift
;;
esac
while [[ ... ]] && [[ ... ]] || (( ..math test.. ))
do
....
done
Example:
while read file ; do echo ${file%%.raw} ; done < mail.lst
until ls | grep auntie | wc do .... done
for variable in value1 value2 ... valuex
do
....
....
done < something
Example:
for file in $(< mail.lst ) ; do echo ${file%%.raw} ; done
PS3='What do you want?'
# -- defaults to '#?'
# Note 'for' like syntax:
select some_variable in value1 value2 ... valuex
do
....
echo $some_variable $REPLY
case some_variable in
value1 )
echo "$some_variable, the value1 picked"
;;
value2 )
echo "$REPLY, the number picked"
;;
* )
break
;;
esac
done
while getopts ':ab:c' opt
do
# leading ':' or OPTERR=0 turns off weird error message
# for invalid options
case $opt in
a ) process option -a ;;
b ) process option -b
...$OPTARG... ;;
# ':' following b indicates an argument stored in OPTARG
c ) process option -c ;;
\? ) echo $USAGE ; exit ;;
esac
done
shift $(( $OPTIND - 1 ))
# -- a piece of boilerplate to sweep options out of the way
# typically leaving file names
function something
{
local myvar='avalue'
....
return 1
....
return 0
}
otherthing ()
{
local yourvar
....
return n ;
}
# .kshrc for OS/2 version of ksh
# NOW CALLED os2.ksh -- d.e.l. 30/10/98
# the below 4 lines expriment for shelling from k2
# if [[ $1 = '/C:' ]]
# then
# shift
# fi
set -o trackall
set -o ignoreeof
# set -o noglob
set +o noglob
alias a:='cd a:.'
alias b:='cd b:.'
alias c:='cd c:.'
alias d:='cd d:.'
alias e:='cd e:.'
alias f:='cd f:.'
alias g:='cd g:.'
# Below (to z:) added by D.E.L. 25/10/98
alias h:='cd h:.'
alias i:='cd i:.'
alias j:='cd j:.'
alias k:='cd k:.'
alias l:='cd l:.'
alias m:='cd m:.'
alias n:='cd n:.'
alias o:='cd o:.'
alias p:='cd p:.'
alias q:='cd q:.'
alias r:='cd r:.'
alias s:='cd s:.'
alias t:='cd t:.'
alias u:='cd u:.'
alias v:='cd v:.'
alias w:='cd w:.'
alias x:='cd x:.'
alias y:='cd y:.'
alias z:='cd z:.'
# end of alias added by D.E.L. 25/10/98
alias h='fc -l'
alias j='jobs'
#alias which='type'
alias back='cd -'
alias cls='print -n "\033[H\033[2J"'
alias dir='cmd /c dir'
alias del='cmd /c del'
alias copy='cmd /c copy /v'
# alias start='cmd /c start'
function start {
cmd /c $* &
}
# d.e.l. alias ll='ls -lsAFk'
# d.e.l. alias lf='ls -CAFk'
# d.e.l. alias cp='cp -p'
# d.e.l. alias ls='ls -F'
# d.e.l. clock_p () {
# d.e.l. PS1='${__[(H=SECONDS/3600%24)==(M=SECONDS/60%60)==(S=SECONDS%60)]-$H:$M:$S}>'
# d.e.l. typeset -Z2 H M S; let SECONDS=`date '+(%H*60+%M)*60+%S'`
# d.e.l. }
unalias login newgrp
if [ "$KSH_VERSION" = "" ]
then PS1='$PWD>'
return
fi
set -o emacs
# d.e.l. bind ^Q=quote
# d.e.l. bind ^I=complete
## d.e.l. bind ^[^[=list-file
#The next four have been preprogrammed
# d.e.l. bind ^0H=up-history
# d.e.l. bind ^0P=down-history
# d.e.l. bind ^0K=backward-char
# d.e.l. bind ^0M=forward-char
# d.e.l. bind ^0s=backward-word
# d.e.l. bind ^0t=forward-word
# d.e.l. bind ^0G=beginning-of-line
# d.e.l. bind ^0O=end-of-line
# d.e.l. bind ^0w=beginning-of-history
# d.e.l. bind ^0u=end-of-history
# d.e.l. bind ^0S=eot-or-delete
typeset -u RW=${RUNWORKPLACE%%.EXE*}
RW=${RW##*\\}
case ${RW} in
EMACS )
FCEDIT=emacsclient
EDITOR=emacsclient
VISUAL=emacsclient
;;
* )
FCEDIT=t2
EDITOR=t2
VISUAL=t2
;;
esac
unset RW
# PS1='[!]$PWD: '
# PS1='[$$:!]$PWD: ' # B. Rosenberg, p. 297 suggested change
PS1='[$PPID:$$:!:$!!]$PWD: ' # B. Rosenberg, p. 297 suggested change
# done for a test PS1='[$!!]$PWD: ' # B. Rosenberg, p. 297 suggested change
# ###---needed for the value of '$!' - shell
# changes mere $! to $<some#>
function pushd {
if [ $# -eq 0 ]
then d=~
set -A dirstk ${dirstk[*]} $PWD
cd $d
else for d in $*
do if [ -d $d ] && [ -r $d ] && [ -x $d ]
then set -A dirstk ${dirstk[*]} $PWD
cd $d
else echo "$d: Cannot change directory"
break
fi
done
fi
echo ${dirstk[*]} $PWD
unset d ;
}
function popd {
if [ ${#dirstk[*]} -gt 0 ]
then let n=${#dirstk[*]}-1
cd ${dirstk[$n]}
unset dirstk[$n]
echo ${dirstk[*]} $PWD
else echo "popd: Directory stack empty"
fi
unset n ;
}
###################################### below stuff added by D.E.L.
function find {
# d.e.l. 31/10/98 part of fix for find problem
# echo ${@+"$@"}
# echo $3
# f.cmd ${*+"$*"}
# print ${*+"$*"}
# f.cmd ${*+"$*"}
# f.cmd ${*+"$*"}
# f.cmd $*
# print ${*+"$* "}
f.cmd ${*+" $* "}
# A--A------ note that spaces here is critical
# or strip in ReXX wrapper function
# will strip the parameter of needed quotes
}
# function find {
# # d.e.l. 30/10/98 part of fix for find problem
# target=$1
# shift
# prs=''
# while [[ ! $1 = '' ]]
# do
# prs="$prs $1"
# shift
# # echo "f.cmd $target $prs"
# f.cmd $target $prs
# done
#
# }
# alias dir='set +o noglob ; cmd /c dir ; set -o noglob'
function head
{
typeset -i lines
case $1 in
[1-9]*([0-9]) ) (( lines = $1 ))
shift
;;
-[1-9]*([0-9]) ) (( lines = 0 - $1 ))
shift
;;
[0-] ) (( lines = 10 ))
shift
;;
'' ) (( lines = 10 ))
;;
* ) (( lines = 10 ))
;;
esac
for file
do
sed "$lines""q" $file
done
unset file
}
function tail
{
typeset -i lines
case $1 in
[1-9]*([0-9]) ) (( lines = $1 + 1 ))
shift
;;
-[1-9]*([0-9]) ) (( lines = 0 - $1 + 1 ))
shift
;;
[0-] ) (( lines = 11 ))
shift
;;
'' ) (( lines = 11 ))
;;
* ) (( lines = 11 ))
;;
esac
# print last 10 lines of file (emulates "tail")
# sed -e :a -e '$q;N;11,$D;ba'
for file
do
# print last 10 lines of file (emulates "tail")
sed -e ":a; \$q;N;$lines,\$D;ba" $file
done
unset file
}
function rev {
if [[ $1 = @(*([/-])*42|*([/-])*[hH?]|*([/-])[hH][eE][lL][pP]) ]]
then
print
print 'usage: rev <filename> # reverses characters on each line of stdin or file'
print
return 1
fi
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//' $*
return
}
function html2txt {
# remove most HTML tags (accommodates multiple-line tags)
sed -e ':a' -e 's/<[^>]*>//g;/</N;//ba' $*
}
function ansi2txt {
# from ANSI2TXT.SED
#
# CAREFUL -- note the EOL escapes
sed -e ':p' -e \
's/^[[[=?c]/^[/g;t p;s/^[[0-9r]*[:;]/^[/g;t p;s/^[[0-9fH]*[A-Za-z]//g;s/[^[^A^H]//g' \
$*
# sed -e ':p;s/^[[[=?c]/^[/g;t p;s/^[[0-9r]*[:;]/^[/g;t p;s/^[[0-9fH]*[A-Za-z]//g;s/[^[^A^H]//g' \ $*
}
function uniq {
# delete duplicate lines from a sorted file (emulates "uniq"). First
# line in a set of duplicate lines is kept, the rest are deleted
sed '$!N; /^\(.*\)\n\1$/!P; D'
}
function sgrep {
# echo "$*"
# echo "'/$*/p;'"
# sed.exe -e '/^/d;'
${SCRATCH}:/sed.exe -n -e "/$*/p;"
}
# seders
function manual {
# pushd c:/os2/apps
# unzip manual.zip $1 -d ${SCRATCH:-M}:/
# del ${SCRATCH:-M}:\\$1
# echo ${SCRATCH:-M}:\\$1
# echo enter return to continue
# read
# popd
cd ${SCRATCH:-M}:/
case ${1:-?} in
-? | /? | ? | 42 | /h )
# unzip -Z -1 c:/os2/apps/manual.zip -d ${SCRATCH:-M}:/ | sort ;;
unzip -Z -1 c:/os2/apps/manual.zip | sort ;;
* )
unzip c:/os2/apps/manual.zip $1 -d ${SCRATCH:-M}:/ > NUL
# tk $1
# ${FCEDIT} $1
${FCEDIT} $1
del $1
;;
esac
cd - > NUL
}
function tee {
# set -x
# above for debugging
if [[ $1 = '-a' ]] || [[ $1 = '-A' ]]
then
shift 1
set apptrigger=on
print -u2 'Append switch not implimented yet...'
return 13
fi
# I thought the below would be needed, but
# apparently OS/2 port of SED does not have the 10 file write limit.
# D.E.L. 12/11/98
# if (( $# > 10 ))
# then
# print -u2 'Too many files (more then 10) specified....'
# return 13
# fi
cmd=
for i in ${@:-con}
do
if [[ $i = '-' ]]
then
cmd="$cmd -e \"w con\""
else
cmd="$cmd -e \"w $i\""
fi
done
eval sed $cmd
}
function iwget {
echo $1 >> k:/www/wget${2:-3}.lst
# for a default wget recursion level of 3
}
function expr {
# from "UNIX Shell Programming", revised edition, Kochan & Wood
# p. 356
integer local="$*" # local integer variable
echo $local # print out result
}
# function tkill {
# pkill=${1}
# # for tbkilled in $( ps | sed -n "/ $$ /s/$$.*//p" )
# echo $( ps | sed -n "/ ${pkill} /s/${pkill}.*//p" )
#
# # for tbkilled in $( ps | sed -n "/ ${pkill} /s/${pkill}.*//p" )
# # do
# # # ps -9 ${tbkilled} 2>&1 > NUL &
# # start ps -9 ${tbkilled} 2>&1 > NUL &
# }
#
#
# trap "tkill $$ &" 2 3
alias ren='cmd /c ren'
alias detatch='cmd /c detach'
# alias wps='cd c:\os2 ; cp pmshell.exe dodge.exe ; start /n dodge'
# alias spw='cd c:\os2 ; go -ka dodge.exe ; rm dodge.exe'
alias cd..='cd ..'
alias cd.='cd .'
alias cd/='cd /'
alias cd-='cd -'
alias cd~='cd ~'
alias md='cmd.exe /c md'
alias rd='cmd.exe /c rd'
alias mkdir='md'
alias rmdir='rd'
alias zipinfo='unzip -Z'
alias cp='cmd.exe /c copy /v'
alias move='cmd.exe /c move '
alias mv='cmd.exe /c move '
alias fg='go -j'
alias vi='vile '
alias view='vile -R '
alias viewinf='c:/os2/view.exe '
# experimental:
function xcp {
echo $*
xcopy.exe $* /v
}
alias cat='sed -n "/^/p"'
# alias rm='cmd.exe /c del /n'
alias source='.'
alias cx='cmd.exe /c'
alias ctype='cmd.exe /c type'
# These next two are in developement
# alias ctime='cmd.exe /c \( echo. | time \)'
# alias cdate='cmd.exe /c \( echo. | date \)'
alias ctime='cmd.exe /c time'
alias cdate='cmd.exe /c date'
# alias \/C='-c ' # for testing 05/12/98 d.e.l.
# alias \/c='-c ' # for testing 05/12/98 d.e.l.
alias remove='. remove.ksh' # to more safely remove the ATAPI zip disk
# alias t2='tk'
alias tk='t2'
alias infozip='unzip -Z '
alias lynx='. lynx.ksh'
# function ls { set -o noglob ; dir $* /N ; set +o noglob ; }
# ils == Inside ls
function ils { dir $* /N /L ; set +o noglob ; }
alias lss='set -o noglob ; ils '
# function ls { lss $* | sed '/-.*-/!d' ; }
function ls { lss $* | sed -n '/-.*-/p;/^.:\\/p;' ; }
# alias rm='cmd.exe /c del /n'
function irm { cmd.exe /c del /n $* ; set +o noglob ; }
alias rm='set -o noglob ; irm '
if [[ ! -a $SCRATCH:\cmd.exe ]]
then
xcopy c:\os2\cmd.exe $SCRATCH:\*.* /v 2> NUL 1> NUL
if [[ $- = 'i' ]]
then
print 'CMD.EXE installed on the scratch volume....'
fi
else
if [[ $- = 'i' ]]
then
print 'CMD.EXE already installed on scratch volume....'
fi
fi
export OS2_SHELL=$SCRATCH:\CMD.EXE
# NATURAL=C:\OS2\CMD.EXE
if [[ ! -a $SCRATCH:\sed.exe ]]
then
xcopy c:\os2\sed.exe $SCRATCH:\*.* /v 2> NUL 1> NUL
if [[ $- = 'i' ]]
then
print 'SED.EXE installed on the scratch volume....'
fi
else
if [[ $- = 'i' ]]
then
print 'SED.EXE already installed on scratch volume....'
fi
fi
# export NATURAL
export NATURAL=C:\OS2\CMD.EXE
# COMSPEC='c:\os2\ksh.exe'
# export COMSPEC
export COMSPEC='c:\os2\ksh.exe' # so far, the normal setting
# export COMSPEC='c:\os2\ksh.exe -i' # this seemed to work better with k2
# export ENV=c:\kshrc.ksh -- replaced with patch to KSH environmental variable
alias cn="COMSPEC=$SCRATCH:\\cmd.exe "
# 'Comspec Native' to enable shelling out & calling outside
# programs more easily with some apps
# HOME=C:/
# export HOME
export HOME=C:/
if [[ $- = 'i' ]]
then
print 'Hello, this is os2.ksh....'
fi
# set -o emacs -- emacs? is this guy crazy? d.e.l. 28/10/98
set -o vi
# Stuff for U2/Until support:
export UNTIL_SYM='c:/os2/apps'
# Stuff for PERL5 support:
# export PERL5LIB='c:/os2/apps/perl/mine;c:/os2/apps/perl/lib;l:/perl/lib'
# export PERL5LIB='L:/PERL/LIB;l:/perl/lib'
export PERL5LIB='l:/perl/lib;l:/perl/lib/auto/OS2/REXX'
# export PATH="l:\perl;$PATH"
# export SETBEGINLIBPATH=''
# export BEGINLIBPATH='l:\perls\lib\auto\OS2\REXX'
# export PERL5LIB='l:\perl\lib'
# export PERL5LIB='c:/os2/apps/perl/mine;c:/os2/apps/perl/lib;l:/perl/lib;l:/perl/lib/auto/OS2/REXX'
# export PERL5LIB='c:\os2\apps\perl\mine;c:\os2\apps\perl\lib;l:\perl\lib'
export PERL5LOAD=10
export PATH="$PATH\.;\..;"
export CDPATH="./;c:/;c:/os2;e:/;e:/tcpip"
# temp
# alias -x xxcp='xcp k:*.* l:*.* /s /v /e '
alias /c=''
alias help='COMSPEC=c:\os2\cmd.exe help '
alias emacs='emacsclient '
# alias stty="echo "
# alias stty="ansi on "
| ABC | string literals |
| ? | single character |
| * | zero or more characters |
| [abco-s] | character class |
| [!k-l] | negated character class |
| ?(pat1|pat2|...) | 0 or 1 patterns |
| @(pat1|pat2|...) | exactly 1 patterns |
| *(pat1|pat2|...) | zero or more of patterns |
| +(pat1|pat2|...) | one or more of patterns |
| !(pat1|pat2|...) | none of patterns |
abc{e,f,g}hij -> abcehij abcfhij abcghij
${variablename} - basic form
Two orthogonal purposes:
again:
trap "echo 'Hello, world'" 2 3
cat <<very_special_message yadda, yadda, yadda yadda, yadda, yadda yadda, yadda, yadda very_special_message
| <<end_label | basic - interpolates |
| <<'end_label' | turn off interpolation |
| <<"end_label" | turn off interpolation |
| <<- | strip leading tabs |
man -k/apropos
suggested list from Linux Magazine, May 2001 p. 24 Bill McCarty
AT&T Unix 'First Edition', (p. 41-42, Salus)
Version 7 additions, (Salus, p. 146)
(* - I haven't actually read yet.)
c) web sites