KSH - Korn Shell Tutorial


Matching Patterns


pattern:    example:      matches:                    not matched:
------------------------------------------------------------------
*           boo*          boot,boo,booth

?           boo?          boot                        booth
[...]       [aeiou]*      ark                         bark
[!...]      boo[!st]      boor                        boot
*(cc|cc)    boo*(ze|r)    boo,boor,booze,boozer       boot
+(cc|cc)    boo+(ze|r)    boor,booze,boozer           boo
?(cc|cc)    boo?(ze|r)    boo,boor,booze              boozer
@(cc|cc)    boo@(ze|r)    booze,booth                 boo
!(cc|cc)    boo!(ze|r)    booth,boo,boot              booze,boor
{c,c,c}     a{b,c,d}e     abe,ace,ade                 axe


Conditional Statements


format                           "true" if:
---------------------------------------------------
(( _num1_ == _num2_ ))           numbers equal
(( _num1_ != _num2_ ))           numbers not equal
(( _num1_ < _num2_ ))            num1 < num2
(( _num1_ > _num2_ ))            num1 > num2
(( _num1_ <= _num2_ ))           num1 <= num2
(( _num1_ >= _num2_ ))           num1 >= num2

[[ _str1_ == _str2_ ]]           strings equal
[[ _str1_ != _str2_ ]]           strings not equal
[[ _str1_ < _str2_ ]]            str1 precedes str2
[[ _str1_ > _str2_ ]]            str1 follow str2
[[ _str1_ = _pattern_ ]]         str1 = pattern
[[ _str1_ != _pattern_ ]]        str1 != pattern
[[ -z _str_ ]]                   str is null
[[ -n _str_ ]]                   str is not null

[ x=y -o k=j ]                   or in expression
[ x=y -a k=j ]                   and in expression


Test Objects (Files, Directories, etc.)


test "true" if:                 ksh
-----------------------------------
object exist                    -a
readable                        -r
writable                        -w
executable                      -x
non-zero length                 -s
zero length


directory                       -d
plain file                      -f
symbolic link                   -h
named pipe                      -p
block special file              -b
character special file          -c
soft link                       -L
socket                          -S

owned by me                     -O
owned by my group              not

"sticky" bit set                -k
set-group-ID bit set            -g
set-user-id bit set             -u

opened on a terminal           not


Format of flow control functions


"if-then"               if _expr_ then
                            _cmd(s)_
                        elif _expr_
                            _cmd(s)_
                        else
                            _cmd(s)_
                        fi

"case"                  case _word_ in
                            _pattern1_)   _cmd(s)_
                            _pattern2_)   _cmd(s)_
                            *)            break ;;
                        esac

"while"                 while _expr_ do
                            _cmd(s)_
                        done

"for"                   for _variable_ in _list_
                            _cmd(s)_
                        done

"until"                 until _expr_
                        do
                            _cmd(s)_
                        done


POSITIONAL PARAMETER


program, function or shell                         $0
argument 1 through 9                               $1 .. $9
nth argument                                       ${n}
number of positional parameters                    $#
every positional parameter                         $@, $*
decimal value returned by last executed cmd        $?
pid of shell                                       $$
pid of last backgrounded command                   $!


REDIRECTIONS


0             stdin
1             stdout
2             stderr

<&-           close stdin
>&-           close stdout
<>filename    open filename for read-write
2>&1          open 2 for write and dup as 1

Examples:
  cmd 2>/dev/null
  cmd >/dev/null 2>&1
  exec 1<&-           # close descriptor 1
  exec 2<&-           # close descriptor 2
  exec 1< /dev/null   # open descriptor 1
  exec 2< /dev/null   # open descriptor 2



Stylish Modern Furniture | Asian Furniture | Antique Dining Room Furniture | Elite Kitchens | Kitchen and Bath Corner | Homemaker Herald | Home Tips

OTHER FUNCTIONALITIES


cmd1 || cmd2    exec cmd2 if cmd1 fail
cmd1 && cmd2    exec cmd2 if cmd1 is OK

V1=${V2:=V3}    Set V1 with the value of V2 if this is set else set the
                variable V1 with value of V3 (V3 could be a number).
                sh replacement:  if [ $V2 ] ; then
                                                V1=$V2
                                 else
                                                V1=$V3
                Example: DisplaySize=${LINES:24} ; Command=${Command:"cat"}


${V1:?word}     if V1 set  & V1!=null   ret $V1 else print word and exit
                  : ${V1:?"variable V1 not set on null"}
${V1:=word}     if V1 !set | V1==null   set V1=$word
${V1:-word}     if V1 set  & V1!=null   ret $V1 else ret word
${V1:+word}     if V1 set  & V1!=null   ret word else ret nothing
${V1##patt}
${V1#patt}      if patt are found at the begin of V1 return V1 whitout the patt
                else return V1
                V1="lspwd" ; ${V1#"ls"}  # exec pwd
${V1%%patt}
${V1%patt}      if patt are found at the end of V1 return V1 whitout the patt
                else return V1
                V1="lspwd" ; ${V1%"pwd"}  # exec ls


COPROCESS


La ksh permette di lanciare uno o piu' comandi come processi in background.
Questi processi sono chiamati coprocesses e sono utilizzati per comunicare
con un programma.
Un coprocess si crea mettendo l'operatore |& (pipe, ampersand) dopo un commando.
Entrambi stdin e stdout del commando sono piped verso il tuo script.
Un coprocess deve incontrare le seguenti restrizioni:
·	Includi un new-line alla fine di ogni messaggio
·	Manda ogni messaggio di output allo standard output
·	Pulisce il suo stdout dopo ogni messaggio

L' esempio dimostra come l'input e' passato verso e ritornato da un coprocess:
  echo "Initial process"
  ./FileB.sh |&
  read -p a b c d
  echo "Read from coprocess: $a $b $c $d"
  print -p "Passed to the coprocess"
  read -p a b c d
  echo "Passed back from coprocess: $a $b $c $d"
FileB.sh
  echo "The coprocess is running"
  read a b c d
  echo $a $b $c $d
L'output risultante e' il seguente:
  Initial process
  Read from coprocess: The coprocess is running
  Passed back from coprocess: Passed to the coprocess

Il comando 'print -p' ti permette discrivere verso il coprocess.
Per leggere dal coprocess, lancia il comando 'read -p'.


EXAMPLES


- Explode a command for use parameters counter
    set `who -r` ; [ "$8" != "0" ] && exit

- declare a variable for only uppercase/lovercase chars
    typeset -u VAR ; VAR="lower" ; echo $VAR   -> LOWER
    typeset -l VAR ; VAR="UPPER" ; echo $VAR   -> upper

- exec

- eval - esegue il comando dato come argomento

- let - esegue le operazioni matematiche che passate come argomento
	let "x = x * 5"
	((x = x * 5))		.. altra forma di let



REGULAR EXPRESSION


- ritorna la prima lettera dopo il segno - all'inizio di una stringa
    VAR="-ciao"
    RESULT=`expr "$VAR" : "-\(.\)"`
    echo $RESULT        .. -c
- toglie il '-' iniziale
    VAR="-ciao"
    VAR=`expr "$VAR" : "-*\(.*\)"`
    echo $VAR           .. ciao
- ritorna la lunghezza di una stringa
    VAR="ciao"
    echo `expr length $SHELL`      .. 4
- ritorna l'indice di dove incontra una substringa
    echo `expr index abcdef de`    .. 4
- ritorna 6 caratteri a partire dall'11
    expr substr "Goodnight Ladies" 11 6     .. Ladies


ARRAY


- definisce un array
	set -A Week Sat Sun Mon Tue Wed Thu Fri
- ritorna un elemento dell'array
	echo ${Week[3]}							.. Tue
	id=3 ; echo ${Week[id]}					.. Tue
- stampa tutti gli elemti di un array
	echo ${Week[@]}							.. Sat Sun Mon Tue Wed Thu Fri
- scandisce un array
    for day in ${Week[@]}
    do
        echo $day
    done
- ritorna il numero di elementi in un array
	nelem=${#Week[@]} ; echo $nelem			.. 7