KSH Manual

 

Table of contents

1Sort
1.1Syntax
1.2Ascending/descending
1.3Numeric sort
1.4Suppress equal lines
1.5Sort on columns
2Variables
3Special Variables
3.1Process variables
3.2System variables
4Conditional expressions
4.1String conditions
4.2Numeral conditions
4.3File conditions
4.4Expression conditions
5Loops
5.1If-then loop
5.2For loop
5.3Select loop
5.4While loop
5.5Until loop
5.6Case loop
6Examples
6.1Read fullname in passwd file
6.2Check if logincode exists in listfile
6.3Wait for a variable in a file
6.4Read lines from a file
7Vi basic commands
7.1Cursor movement
7.2Textmode
7.3File management
7.4Yanking (buffer)

1 - Sort

Unix has standard sorting functionality. The command sort has all sorting functionality you wish.

1.1 - Syntax

Sort can be used in 2 ways, first as single command. Second as piped command. Output will be displayed or piped to standard output if no output file is specified.
sort [-options] [-o outputfile] inputfile

cat inputfile | sort [-options] > outputfile
Most common used options are listed in below. If no input file is specified, sort assumes standard input.

1.2 - Ascending/descending

By default sort sorts a file ascending based on the ASCII value. To sort descending the option -r must be used.
sort -r inputfile

1.3 - Numeric sort

Sort will sort based on the ASCII value of a line beginning with the first character. So 10 becomes before 9 because the value of the first character of 10 is 1, and 1 comes before 9. To sort on whole numbers use the -n option.
sort -n inputfile

1.4 - Suppress equal lines

Duplicate lines will also be sorted and displayed. To print only 1 line in case of one or more duplicates, use the option -u.
sort -u inputfile

1.5 - Sort on columns

By default sort sorts based on the whole line. To sort on columns use the -k option. The default field separator is a space or tab. This default can be changed by the -t option.
sort -t ';' -k 4 inputfile
The above command will sort the input file by column 4 (first column is 1). The fields are separated by a ; (semi-column). Use the quotes when using special characters.

To numeric sort a column the -k and -n option may be combined to e.g. -k 4n.

2 - Variables

Like other program languages, Unix uses variables. Use the command env to display the environment variables.

It is not necessary to declare the variables in Unix like in other languages. Variables can be filled with almost anything, however there are some special Unix characters. E.g., if you want to insert a * in a variable, Unix handles the * the same way as in ls * (places the filenames of a directory at the place of the *). To use the real character quotes must be used. Some examples are placed below:
number=1
word=test
startuppath="/usr/scripts/testscript.sh"
The first variable 'number' will be filled with the number '1'. The second variable will be filled with 'test', and the third variable will be filled with the path. To use the / (slash) in the last variable, quotes are used to tell Unix not to treat the slash as a special character.

There is no space around the '=' character in the above example. Do not put spaces here, or Unix will think the variable is a command.

To display a variable, a $(dollar) sign must be placed before the variable. Some Unix versions use the following syntax to display a variable: ${number}.

The Unix shell replaces the name of the variable by the contents of the variable. This way variable can be used in almost any situation. Variables may also be used in a Unix command string, or even as a Unix command itself. Some examples:
echo This is the startuppath ${startuppath}
cp ${word} /tmp/${word}
By entering options to a script, variables can be filled before starting the script. Options must be separated by a space. The options will be put in a numbered variable. The display the first option ad the command echo ${1}. This prints the value of the first option-variable. The second option variable is ${2} etc.

Variables can only be used within the started shell. If a script is executed, it's started in its own shell. This means that the variable will be lost when the script ends. It is however possible to export a variable so it will be saved when the script ends. The command to do this is export.
var1=test
export var1

export var2=100

3 - Special Variables

Unix uses a number of special variables which contain information about the system and its processes. This information can be used in scripts by calling these variable.

3.1 - Process variables

The following variables contain information of the started process (or command). These variable are read-only.
VariableDescription
$!Process id of the last background process started.
$$Process id of the current shell.
$?Exit status of the last command executed. If killed by a signal the exit status is signal number + 128.
$#Number of positional parameters.
$*All positional parameters.
$1 ... $9The specific positional parameter.
A positional parameter is a parameter given to the script on the command line.
myscript.ksh option1 option2
The first positional parameter $1 contains the string "option1", the second positional parameter contains "option2". The string $* contains "option1 option2".

Exit codes can be generated in scripts by using the return command. A return 1 will result in a exit code 1.

3.2 - System variables

System variables contain information about the system.
VariableDescription
$HOMEThe current users home directory.
$PATHA colon separated list of directories, in which Unix searches for the executed command.
$PWDCurrent working directory.
$RANDOMGenerated a random number.
$USERThe current users login code.

4 - Conditional expressions

By creating conditions it is possible to use loops in scripts. If a condition is true, a command is executed or not.

In this chapter the most common options are explained. There are a lot more options in Unix, and even more option is some specific Unix versions. In the Unix man pages (man ksh) all options are listed and explained.

4.3 - String conditions

String conditions are used to control a script based on the value of a variable. One or more variables can be checked on its contents based on value or kind of information.
ConditionDescription
-n stringTrue if length of string is not equal to 0
-z stringTrue if length of string is equal to 0
string1 = string2True if string1 is equal to string2
string1 != string2True if string1 is not equal to string2
string1 < string2True is ASCII value of string1 is less than ASCII value of string2
The next example will display 'good' when var1 has a value.
if [-n ${var1}] then echo good
The use of loops is explained in a next chapter.

4.4 - Numeral conditions

String conditions compare the values of the string based on the ASCII value of the string. To use the numeral value of the sting the options below must be used.
ConditionDescription
string1 -eq string2True if value of string1 equals string2.
string1 -ne string2True if value of string1 not equals string2
string1 -lt string2True if value of string1 is less than the value of string2
string1 -gt string2True if value of string1 is more than the value of string2
string1 -le string2True if value of string1 is less or equal to value of string2
string1 -ge string2True if value of string1 is more or equal to value of string2

4.5 - File conditions

Sometimes it is necessary to manipulate a script based on a file of directory. For instance if a file exists or not.
ConditionDescription
-a fileTrue if file exists.
-d fileTrue if file is directory.
-h fileTrue if file is symbolic link.
-k fileTrue if file has a sticky bit.
-r fileTrue if file is readable.
-s fileTrue if file contains more than 0 bytes.
-w fileTrue if file is writable.
-x fileTrue if file is executable or directory is accessible.
-H fileTrue if file is hidden.
-O fileTrue if file is owned by current user.
-G fileTrue if file is owned by current group.
file1 -nt file2True if file1 is newer than file2.
file1 -ot file2True if file1 is older than file2.
file1 -ef file2True if file1 and file2 point to the same file.
In the above table with a file we mean an entry in the fat table. A file can be a file, directory, link or device etc.

4.6 - Expression conditions

To combine expressions some logical commands can be used.
ConditionDescription
! exprLogical not. True if expression is not true.
expr1 || expr2Logical or.. True if expression 1 or expression 2 is true.
expr1 && expr2Logical and.. True if both expression 1 and expression 2 are true.
The next example is a combined expression:
if [[ -n ${var1} && ${var2} = ${var3} ]]
The condition is true if var1 is not empty and var2 and var3 are equal.

5 - Loops

Scripts can be controlled by loops, loops are manipulated by conditions. If a condition is true execute a part of the script, or while a conditions is true etc.

Loops can be cascaded, this means that other loops may be programmed within other loops. It is however recommended to use tabs like in the examples or your program will be unreadable.

In this chapter only the most common used loops and there options are explained.

5.5 - If-then loop

The most simple and common used loop is the if-then loop. If an expression is true, execute the command(s). An extra option is the else option. If an expression is not true execute the command(s) after else. The loop must be closed by the fi command.
if expression1
        then
                function1
        elif expression2
        then
                function2
        else
                function3
fi
If expression1 is true then execute function1. If expression1 is not true but expression2 is true, execute function2. If both expression1 and expression2 are not true execute function3.

5.6 - For loop

For loops are used to execute a command with a range of entry's.
for identifier [in word...]
        do
        function
done
The command executes the function for all values in word. If combined with Unix commands a powerful loop is generated. Look at the example chapter for a more detailed description.

The for loop must always be closed by done.

5.7 - Select loop

The select loop is the interactive version of the for loop. The select command displays all values in word. The user can select the values by entering the line number. The loop will than execute the function with the selected value.
select identifier [in word...]
        do
        function
done
The select loop must also be closed by done.

5.8 - While loop

While loops will execute the function as long the expression is true.
while expression
        do
        function
done
Also the while loop must be closed by done.

5.9 - Until loop

This is the opposite of the while loop. The function will be executed until the expression is true.
until expression
        do
        function
done
Again close the loop with done.

5.10 - Case loop

With the case loop it is possible to manipulate a script based on the users choice. It's also possible to use this loop with a variable. The case loop executes a function based on the value of the identifier (variable).
case identifier in
        word) function
        ;;
esac
The case loop will execute a function and then returns to the beginning of the loop. The cases must be closed by ;; and the loop is closed by esac. To really exit the loop the exit command must be used.

The example below is a standard yes/no question:
case ${i} in
        y) echo "Continue"
        ;;

        n)	echo "Ok, you out of here"
                exit
        ;;

        *)	echo "Illegal choice"
        ;;
esac
The loop asks the user to enter a key that is used to fill variable i (only cursor on screen). If the value is y, the message Continue is printed. If the value is n, the loop is stopped. All other choices display the last message. Only by entering a 'n' the loop is stopped.

The case loop can only be stopped by the command exit in the script or a ctrl-c (if not disabled!).

6 - Examples

In this chapter some part of scripts that I use myself are displayed. The scripts are solutions for common problems. Scripts I get from other people are marked by the name of the person who provided the script.

I regularly update this page since I don't know everything yet...

6.3 - Read fullname in passwd file

Sometimes we want to know the full name of a user based on the login code of that user. The next example displays the full name belonging to the login code.
awk -F":" '{if($1 == "'${login}'"){print $1 " " $8}}' /etc/passwd
The variable $login must be filled with the login code of the user.

6.4 - Check if logincode exists in listfile

For maintenance scripts, it is sometimes necessary to exclude some login codes (like root). The easiest way to do this is generate a list of login codes which must be excluded. Than let the script read the list of login codes.
if [ -z "`cat loginlist | grep ${login}`" ]
        then
        commando...
fi
If the login code exists in the login list file, the expression is filled and the condition will become not true. The command is skipped for that user.

6.5 - Wait for a variable in a file

To start scripts if one or more previous scripts are ready, I use the following script. Because it is not possible to export variable to other users. A temporary file must be used.

By example, let's take 3 scripts. Script 3 is started if the first 2 are ready. Before all 3 scripts are started the file var must be filled with the number 2.

The first 2 scripts must end with the following commands.
count=`cat var`
count=`expr ${count} - 1`
echo ${count} > var
The 3rd command writes the value of count back to file var. If both scripts are ready the value of file var will be 0.

The next part must be entered at the start of the 3 script.
count=`cat var`
while [ "${count}" -ne "0" ]
do
        sleep 60
        count=`cat var`
done
Read the value of file var. While var is not equal to 0, wait until it is.

6.6 - Read lines from a file

I have found 3 ways to read a file line by line. If you find other ways to do this, please email them.
The fist example is the most simple one. But the file can't contain any spaces or tabs. The Unix script will use the space, tab and new line character as field separator.
for rec in `cat datafile`
do
        echo ${rec}
done
The next one is a more complex example. It fist converts all spaces to pipes. So the file doesn't contain any spaces anymore.
for rec in `cat datafile | sed -e 's/ */|/g`
do
        echo ${rec}
done 
The only disadvantage of this example is that it changes the lines of the file. The last example doesn't change the lines of the files and reads the whole line at once. Only the performance is real bad, for every line the file must be opened again.

row=0
for i in `cat datafile`
do
        row=`expr ${row} + 1`
        rec=`tail -${row} file | head -1`

        echo ${rec}

done
I use this script only for small files, and if there is no other alternative.

7 - Vi basic commands

This chapter contains the basic vi commands. Most commands can be combined to make more complex commands.

7.1 - Cursor movement

These commands are used for cursor movement.
Key(s)Description
hMove cursor left.
lMove cursor right.
jMove cursor down.
kMove cursor up.
$Move cursor to end of line.
0Move cursor to start of line.
wMove cursor to first character of next word.
bMove cursor to first character of previous word.
[CTRL] uMove one page up.
[CTRL] dMove one page down.

7.2 - Textmode

Vi starts in command mode. To enter text the mode has to be changed to textmode. There are 4 ways to change to textmode. To leave textmode press [ESC].
Key(s)Description
aAppend text after the current cursor position.
iInsert text before the current cursor position.
oOpen a new line below the current cursor position.
OOpen a new line above the current cursor position.

7.3 - File management

To load or save files use the following commands. To use these commands, enter the command line mode. In command mode enter : (semicolon).
Key(s)Description
qQuit vi only when there are no changes.
q!Quit vi and don't save any changes.
wWrite current file.
w!Write current file, even if it exists.
wqWrite file and quit.
f name Load file.

7.4 - Yanking (buffer)

By default yank uses the undo buffer. Yank can also use named buffers. Buffers can be named by one alphabetic character. (e.g. ayy Yank current line to buffer a, to insert the line use ap).
Key(s)Description
yYank to buffer. Must be specified what to yank (eg. yw Yank word).
yyYank current line to buffer.
pInsert contents of a buffer.