Back to Tylogix Home Page


Exploring iSeries QSHELL

By Thibault Dambrine

Exploring iSeries QSHELL: Concepts & Tutorial

May 2002: Four commercial Linux vendors have joined together their development organizations to produce an industry-standard distribution. Backed by IBM Corp., United Linux plans to release its first distribution later this year and support each of the platforms in IBM's eServer line.

Each of the member companies -- Caldera International Inc., Connectiva SA, SuSE Linux AG, and TurboLinux Inc. -- announced the joint venture in a conference call on May 5, 2002. The joint venture, which includes the developer pools of the member companies, will create an enterprise-class Linux distribution, called United Linux. The companies in turn will sell the distribution with value-added features including technical support and localization.

If over the last few months or years, you thought of acquiring UNIX - or Linux - skills but never had the time, the opportunity or a platform to use it, this article may for you. The iSeries operating system now offers a built-in UNIX environment. This new environment is named QSHELL.

While there has not yet been much publicity, this is an important development for all of us who use the iSeries on a daily basis. It can also be a very strong basic training ground for understanding the basics of how UNIX style operating environments work.

Why QSHELL? The first question one may want to ask is why did IBM come up with this 'QSHELL' environment in the first place? The answer is that to be fully Java compliant, IBM needed to supply a JDK (Java Development Kit) on its iSeries eServer that could run standard Java commands such as Java, Javac or Javadoc, the same way other (UNIX) systems could.

There is only one snag, OS/400 does not happen to be 'a flavor of' UNIX. The OS/400 IBM team resolved this hurdle by supplying a new 'UNIX style shell' on the iSeries and appropriately named it 'QSHELL'.

The purpose of this article is to give a quick overview of how QSHELL works, and provide a strong tutorial base and an example of shell script which can be run on a UNIX platform as well as your own iSeries using QSHELL.

Jumping In

To start QSHELL, simply type the OS/400 command 'STRQSH' on the command line. Once there, what you will see is not very different from an ordinary green-screen QCMD session, with a different set of commands.

The commands available in QSHELL are mostly UNIX style commands. To see what commands are available, you have to do a directory listing (use ls /usr/bin). All the commands reside in this directory, although they are available to be run where ever you are in QSHELL.

The QSHELL command set is based on the POSIX 1003.2 and X/Open Command and Utilities Issue 4, Version 2 standards. It is compatible with Bourne shell scripts and supports many of the features used by Korn shell scripts. What this really means is that you can pick up a standard UNIX Korn Shell script manual and learn how to write a UNIX style procedure that can actually run on your iSeries. There are however some incompatibilities (see Appendix 1) that you may want to understand if you start writing scripts to run in QSHELL.

At first glance

The first thing you will see after entering the QSHELL environment is a screen saying

'QSH Command Entry' , and a '$' character.

As a quick picture, you can think of UNIX environments as similar to DOS, as far as the user command interface is concerned.

To know what you can do with QSHELL, there is no 'HELP' command, and the F4 key is plainly ineffective. If you wish to know what tools you have, you need to get yourself to the /usr/bin directory. To do this, you have to type the command 'change directory to /usr/bin' – the actual command below is

cd /usr/bin  

From there, you can confirm where you are by typing a 'Print Working Directory' – the actual command below is

pwd

Once there, you can see the contents of the /usr/bin directory by using the command

ls 

or as I prefer to use it,

ls –ltra

in this case, the command modifiers

'a' means 'all', do not hide the directory entries starting with '.'

'l' means 'long', show all the details about each entry

't' means sort by modification time

'r' means reverse order for the sort. Effectively, the latest entries will be the last ones in the listing, which is practical for reading.

Note that the order of these command modifiers is not important. ls –artl is interpreted same as ls –ltra

You can also type, from the original directory the command

ls –ltra /usr/bin

This sounds basic, but ls and pwd are some of the most useful commands. You will use them often in this environment.

The directory structure, in UNIX, starts with '/'. The '/' directory is also known as the 'root' directory. Each directory branch grows from the previous, just like in DOS or in Windows. The directory structure in this environment can have n levels.

The equivalent of the '/' root directory in UNIX in the traditional iSeries environment is the QSYS library. However, on the iSeries, we have a single level of libraries: all libraries are in QSYS, no library can be in a library if it is not QSYS. In UNIX, a directory can be in a non-root directory.

One other important feature of the UNIX file system: unlike the iSeries or NT, it is case-sensitive. This means that a file named caseSENSTIVE is not the same as a file named CASESensitive. They will be listed and recognized by the operating system as two distinct files. This is critical if you write shell scripts.

Back to the command list. Having this list of comnands is great, but what can you do with all this? In a traditional UNIX or Linux environment, you can type

man command_name

For some unknown reason, but the iSeries folks did not implement this. They did not implement the F4 command in QSHELL either. The best source for information on the comands you have there is from the Internet. If you use www.google.com, try searching for (as an example)

unix man pages command_name

You will get all the information you need on pwd. Giving such skimpy help is somewhat out of character for the iSeries, but this is what we have for now.

The first thing you may want to do if you play with your QSHELL environment is to create a directory of your own. As an example, you can type

mkdir /mysandbox

This action of creating a QSHELL directory is similar to creating your own library. Within that directory, you can store your own shell scripts without cluttering the root area, which you want to keep clean if possible.

There are many UNIX commands to play with, and for now, I will focus on the method of using QSHELL rather than explaining too many commands.

The number one use of an environment such as a UNIX shell is, like most computing environments to be able to store programs, or shell scripts. To do this, you need an editor. Again here, we run into one of these differences that make QSHELL different from other UNIX implementations.

 

 

A Shell Scripting Tutorial

 

Like the CL language, in the QSHELL environment, commands can be entered from the command entry screen. In the same way, QSHELL instructions can be written into a script, which can be re-run any time it is invoked. Shell scripts can, like CL programs, take parameters, contain variables and use conditions to process information, make decisions and alter data.

Shell Basics

In an unusual way, in shell programming, the first most important type of line to understand is the comment line.

As in any programming language, it is always good practice to include strong documentation in the code. The hash (#) sign is the comment indicator for shell script. Everything to the right of the # is considered a comment.

However, there is an exception for the comment indicator. This leads into the (real) main topic of this paragraph: Which shell are you using?

At the beginning of any shell script, you must indicate for UNIX what type of shell commands you are intending to use, as each shell has its own variation on the shell theme.

When the hash sign (#) (normally an indication of a comment) is followed by a exclamation mark (!), you are actually telling the system which shell you are aiming to use to run your script. The table below shows 3 different declarations.

Shell Name

Bourne Shell

C shell

Korn Shell

Declaration

#!/bin/sh

#!/bin/csh

#!/bin/ksh

This effectively determines how each command after that line will be interpreted by the operating system.

 

Shell Variables

Simple Variables

The first component of any program is its ability to store values in variables.

Bourne and Korn Shell Variable Assignment

C Shell Variable Assignment

var1='My name is '

var2='Thibault'

To verify what you have in your variables, simply type:

echo $var1 $var2

Note that in a variable assignment, you do NOT want any blank characters before or after the equal sign.

 

For the C shell, the syntax is slightly different:

set var1='My name is '

set var2='Thibault'

To verify what you have in your variables, simply type:

echo $var1 $var2

 

Evaluating Expressions

To evaluate an expression and assign the result to a variable, in Korn shell, you need to use the expression 'let'. Here is an example:

Bourne and Korn Shell Expression Evaluations

C Shell Variables

var1='My name is '

var2='Thibault'

set var1 = 'My name is '

set var2 = 'Thibault'

let counter=4

echo $counter

let counter=3*$counter+5

Note that in a variable assignment, you do NOT want any blank characters before or after the equal sign.

@ counter = 4

echo $counter

@ counter=3*$counter+5

echo $counter

Note: When '@' is used for expression evaluation with the C Shell, you must include a space before and after the equal sign as well as between each element which appears on the right side of the expression.

To verify what you have in your variables, simply type:

echo $var1 $var2

echo $counter

Parameters

The ability to pass parameters or arguments to a program makes shell programming much more flexible than it would be otherwise.

Bourne and Korn Shell Parameter Variables

C Shell Parameter Variables

Arguments are referred to with $n, where n is the sequence of the argument. $1 is the first argument, $2 is the second one and so on, to a maximum of 9.

To get the number of parameters or arguments, the variable $# can be used.

Parameters can be referenced within a shell program by using the reserved shell variable $argv. The first parameter will be $argv[1], the second $argv[2], and so on. The number of parameters passed to the program can also be referenced. The variable to use is $#argv. Logically, you can also refer to the very last argument passed with $argv[$#argv].

 

 

Logic Controls

Shell scripting is a like any other language, and this means it can handle if conditions and loops like any other languages. It does however have its own syntax. Here are the main syntax constructs to remember:

Bourne and Korn Shell Logic Control

C Shell Logic Control

Control statements follow a peculiar but logical naming convention. 'If' groups for example, are terminated with a 'backward if ', spelled 'fi'.

if [condition] then 
    commands to execute
elif 
    alternate commands to execute
fi

In the same way, case groups are terminated with 'case' spelled backwards, or 'esac'.

case 'ValueA':
    commands to run for 'ValueA'
case 'ValueB':
commands to run for 'ValueB'
esac

For loops and while loops are other useful constructs available in shell programming. The syntax is as follows:

for loop_index
    do
        commands
    done 


while 
    (conditions)
do 
    commands
done 

In C Shell, the syntax for 'if' and 'case' statements is slightly different:

if ( condition ) then
      commands to execute
else
      other commands to execute
endif

 

The case construct in C shell is as follows:

switch $variable 
case 'ValueA':
    commands to run for 'ValueA'
    breaksww
case 'ValueB':
    commands to run for 'ValueB'
    breaksww
default:
    default commands to run
    breaksww
endsw

As usual, for the for and do loops, there are slight differences in C Shell:

foreach loop_index argument_list
do
    commands
end


while 
    (conditions)
do 
     commands
done 

 

Pipes and Re-Directions

Unlike the control structures, the pipes and redirection operators work similarly in all shells.

Using pipe commands in shell scripting is very common. A pipe can be compared to using an outfile on an iSeries command, and having it read directly by the next command being called.

Here is an example where the output of command ls (list the contents of the directory) is piped directly into the input of the command sort. All this is done by using the | operator between the two commands:

ls -l | sort 

With re-direction operators, you effectively send the output of your command to an outfile. The operator in this case is '>'. The command date generates data which is appended to the file dateoutput.txt.

date > dateoutput.txt

Working the same way, the '>>' operator appends, instead of replacing the contents of final_results.txt.
sort school_marks_file >> final_results.txt
Conversely, with the reverse operator, the program named program_demo can read its input directly from the file inputdata.txt. 
program_demo < inputdata.txt

To display the contents of the files in these examples, use the cat command.

Putting it all together

For the purpose of this article, the point of application for this shell script tutorial is on your own iSeries eServer. How do you go about creating your first shell program? You are only a few steps away.

In most UNIX flavors, the two editors supplied 99% of the time are either emacs or vi. The viewing utilities are cat and more. Out of these, QSHELL only has cat, a utility which copies the contents of a file to the display screen. This is not very practical for large files. Thankfully, they have replaced these utilities with somewhat better programs.

The editor for QSHELL files and scritps is a command named EDTF. The format of this command is

EDTF STMF(‘/directory/TestShellMenu’)

The file viewer for QSHELL files and scirpts is a command named DSPF. The format for this command is

DSPF STMF(‘/directory/TestShellMenu’)

The only wrinkle in this case is that you cannot access these two commands from QSHELL. You have to use your normal command entry line.

The good news is that EDTF and DSPF are very much like SEU editors and any iSeries programmer should have no difficulty learning how to handle them. Actually, in my opinion, as far as text editors, EDTF is miles ahead of emacs and vi.

 

 

A first Exercise

This article cannot replace a UNIX reference book, but if you have a few minutes, with the example below, you will be able to create your first UNIX shell script on QSHELL.

In Appendix 2, you will find a simple Korn shell menu script. Menus are simple ways of making your life easier and they demonstrate well some basic functions of the scripting language.

As a first step, use the EDTF utility to copy in the source provided in Appendix 2 into a file named MyMenu.

Once this is done, take a look at it in your directory in QSHELL and see if you can do a cat against it. It will simply scroll on the screen.

You can do a cat on this file to display it, but if you type the menu name to execute it, it will not do anything. This is not because the source is not compiled - UNIX shell script is interpreted - it is because of the permission setting which is not set initially to let you execute this file.

If you do an ls –ltra /Mysandbox command while in your directory, you will see your MyMenu file listed, with the following combination of letters in the front:

-rw-rw-rw-  

 

The first '-' means that this is a file. If it was a directory, it would say 'd'

If it was a logical link, it would say a 'l'

The next 9 characters are a repetition of 3 letters for each of 3 groups

The three letters are 'r' representing ' right to read ', 'w' to represent the ' right to write ' and 'x' to represent the 'right to execute'.

The three groups are owner, group and public.

What this all means is that even if you have keyed in a perfectly good menu, you are still not able to execute it because you do not have the right to. You have a '-' where the 'x' would be if you did have that right.

Fortunately, you can change this very easily. The command is chmod,

If you use the command

chmod 744 MyMenu

you will change the permissions settings to

-rwxr--r--

which in effect says you (the owner) are allowed to read, write and execute, but everybody else can only read.

A good chmod tutorial can be found at the following address:

http://catcode.com/teachmod/

Try it!

In Conclusion

This is a very simple introduction to QSHELL. There is much to read on a blend of UNIX and iSeries to be able to do more in this environment. The main point here is that you can, if you wish, start building up UNIX shell scripting knowledge right now, without having to go very far.

As a reference, one of the best books I have bought on the topic is 'UNIX in Plain English, by Keven Reichard and Eric Foster-Johnson. Another good book is 'UNIX Shell Programming' by Lowell Jay Arthur and Ted Burns.

Finally, one of the richest places to grow your UNIX knowledge is the World Wide Web.

This article, in the end, is just a starting point and hopefully an incitement for you the reader to go further.

 

 

Appendix 1
Differences between QSHELL and other interpreters

While qsh is compatible with standard shell interpreters on other platforms, there are several differences:

ls /qsys.lib/QSHELL.lib/*.PGM

 

Appendix 2
A Sample Practice Menu written for QSHELL

The following UNIX shell script is a simple menu with two options:
1 to show the current date
2 to show the content of the current directory
Much more sophisticated scripts can be run instead of these two functions. The point here is to illustrate some basic functionality of shell scripting.

###################################################################
# #
# Simple Menu Shell Script #
# Credit: Internet Code - www.itworld.com #
# Thibault Dambrine #
# #
###################################################################

#! /bin/ksh
# A very simple menu
# The main logic for the program displays the menu
# gets the users entry and initiates the activity
#
#------------------------------------------------------
# MAIN LOGIC
#------------------------------------------------------
# Repeat the menu over and over
# Steps are:
# 1. Display the menu
# 2. 'read' a line of input from the key board
# 3. Check the answer for 1, 2, 3 or 0 and dispatch
# to the appropriate function or exit
# 4 Repeat until 0 is entered
while true
do
# 1. display the menu
echo
echo
echo 'date'
echo
echo
echo
echo
echo
echo
echo '\t\t\t Test Example Menu'
echo
echo
echo
echo
echo
echo '\t\t Please Select:'
echo
echo
echo '\t\t\t 1. Show Today's Date'
echo
echo '\t\t\t 2. List Content of current directory'
echo
echo
echo '\t\t\t'
echo '\t\t\t 0. Exit'
echo
echo
echo
echo '\t\t Select by pressing a number and then ENTER'
# 2. read a line of input from the keyboard
read answer
# 3. Execute commands based on the
# number entered by the user.
case $answer in
1)
echo
echo
echo
echo
date
echo
echo
echo
echo
echo
echo 'Show Today's Date now complete - Press Enter'
read x ;;
2) ls -ltra
echo
echo
echo
echo
echo
echo 'Directory Listing now complete - Press Enter'
read x ;;
# If the user selects 0 to exit then break out
# of this loop
0) break ;;
esac
# Do it again until the user enters 0.
done

 

 

Appendix 3
UNIX Style File Authorities

 

Object authority or 'file permission' in UNIX lingo, is something to both be aware of and get used to. I will go into some detail here because this is a key concept. Understanding how permissions work in UNIX is a necessity for every day operations and it also gives a good indication of the style in which UNIX works.

Each file has 3 sets of 'read/write/execute' flags attached to it, one for the owner, one for the group and one for the public. These 3 flags can be set to 0 or 1. To handle all this in the most economical way, each of the three authority groups are represented by the binary value of an octal number. This octal number, (0 to 7) translated in binary, gives a combination of 3 binary digits. Clear as mud? You need to understand that clearly when you work with UNIX, as this is one concept you will deal with every day. If for example, you write a small shell script test to see what you can do, you will never be able to execute it unless you change the permissions (using the obviously named chmod command) to give yourself permission to execute the file.

A file, in UNIX can be anything from a flat file to a UNIX script. A UNIX script with an 'x' in the 'execute' permission flag position is deemed executable, even if not compiled (shell script is interpreted). Each file has 3 types of permissions (read, write or execute), for each of the three categories of users (individual users, groups of users or all users).

The 0 to 7 values are actually used as a shortcut to say their binary value. For example, the binary value of Octal 5 is '101'. This translates in a permission value of 'r-x' or 'read, no write, execute'. Octal 6 translates to binary '110' and thus the permission value of 'rw-' or 'read, write, no execute'. The table below tells the whole story:

Octal Value

Binary Value

Permission

Directory Listing

0

000

no read, no write, no execute

---

1

001

no read, no write, execute

--x

2

010

no read, write, no execute

-w-

3

011

no read, write, execute

-wx

4

100

read, no write, no execute

r--

5

101

read, no write, execute

r-x

6

110

read, write, no execute

rw-

7

111

read, write, execute

rwx

If a file for example has permission setting 777, it really has permission setting where the owner has rwx (read/write/execute), the group has rwx (read/write/execute) and the public has rwx (read/write/execute) permission. The permission flags look like rwxrwxrwx, listed at the right side of the file in a directory listing.

If a file has permission setting 764, the individual has rwx (read/write/execute), the group has rw- (read/write/no execute), and the public has r-- (read/no write/no execute). The permission flags look like rwxrw-r--, listed at the right side of the file in a directory listing.

You can see the permissions on the files in a directory by doing a ls –l command.

There is more to read on UNIX permissions, but this is the base functionality. Coming from the iSeries environment, this method of determining authority or permissions, looks like a step backwards. It is however widely used and accepted by UNIX lovers the world over. There is no equivalent in UNIX to the notion of 'object' in OS/400 sense. This may help understand this somewhat simple permission system.

 

Back to Tylogix Home Page