The Bash Shell on z/OS®
🖥 🖥 🖥 🖥
In more and more cases, using and administering IBM z/OS requires the use of Unix System Services (z/OS UNIX). This can be a daunting task for those who are used to managing the system with more traditional “green-screen” tools. z/OS comes with the Bourne shell, which will be familiar to people who have used Linux before. Although this shell is compliant with the POSIX specifications, it is not particularly user friendly. In fact, most Linux users would prefer to use the Bash shell (also known as the Bourne-Again Shell). In addition, Apple shipped Bash as the default shell until macOS Catalina.
The default way of interacting with z/OS UNIX is via the Bourne shell, also known as sh
. This is the standard UNIX shell, and it has roots that go back to the 1970’s. While it’s adequate for writing shell scripts for automation purposes, it lacks a number of modern interactive usability features. The bash
shell provides a number of enhancements that can significantly improve your day-to-day activities.
If you’re looking for instructions on how to get bash
onto your z/OS system, scroll down to the “How to Get Bash” section of this article.
What Can I Do With It?
bash
is a drop-in replacement for the default shell on z/OS UNIX. Once executed, it takes over as your interpreter, executing commands on your behalf in the same was that sh
does. If desired, you can (and should!) completely replace the default shell with bash
.
Command-line completion
The bash
feature I find most helpful in my everyday shell usage is command-line completion. This is the ability for the shell to automatically complete commands and their associated arguments. To use this feature, type a few characters in the name of a command, and press the Tab key. bash
will search through all the possible commands that are in your $PATH, and attempt to complete the command name. If the characters you have typed are unique to a single command, then bash
will fill in the complete command name.
For example, if you type his<Tab>
, the shell will automatically complete the command to be history
.
If there is a conflict, then bash will fill in all the characters up until the point where the commands differ, and then let you fill in the rest. If you want to see the conflicting commands, press Tab again for a list.
The bash
shell will also expand arguments to commands. This is especially helpful if you need to pass the name of a long, mixed-case file as an argument.
Command Line Editing
The bash
shell has the ability to let you go back and edit your command lines before submitting them. If you finish typing a line in sh
and realize that you made a mistake in the middle, you have to backspace and erase everything up to the error. If you’re using bash
, you can use the Left and Right arrow keys to move the cursor to the mistake and update it directly.
Bash also has other command line editing capabilities via keyboard shortcuts:
- Ctrl-A moves the cursor to the start of the line.
- Ctrl-E moves the cursor to the end of the line.
- Ctrl-K erases all text from the cursor position to the end of the line.
- Ctrl-U erases all text from the start of the line to the cursor position.
- Ctrl-W erases the word preceding the cursor.
History Retrieval
Another handy feature of bash
is the ability to quickly retrieve previously submitted commands. If you want to get a command that you previously typed, just press the Up arrow key to retrieve it from the command history. Pressing Up multiple times will rewind back through your history until you reach the desired command. If you go too far, you can press the Down arrow and move forward in your history. Once you’ve found the desired command, you can edit it as described above.
History Search
If you want to run a command that you used in the past, but it was a long time ago, you can use the history search feature to find it. Press Ctrl-R, and type some characters that were in the command. bash
will pull up the first command it finds that contains the typed characters. This can be really handy if you have a long command line that you want to retrieve.
Globbing
Unlike some popular programming languages, bash
does not support regular expressions. However, it does have a feature called “globbing”, which provides matching or expanding specific types of patterns. This feature is primarily used for matching filenames or searching file contents.
Brace Expansion
One useful capability of globbing is brace expansion.bash
is able to make creation of complex filename patterns easier. A set of characters within a pair of braces will create a list of results where each character is used in turn.
$ echo b{a,e,i,o,u}t
bat bet bit bot but
$ echo {a,b,c}{x,y,z}
ax ay az bx by bz cx cy cz
Arithmetic Evaluation
bash
has the ability to perform integer arithmetic within a script without requiring an external program. This means that scripts can run quicker with less overhead. This is accomplished via the syntax $((expression))
. Bash will evaluate the contents of the expression and substitute that value in place of the expression. For example:
slope=$(( $m * $x + $b ))
How to Get Bash
There are two ways to obtain a copy of bash
for z/OS:
- Use the version included with the IzODA product.
- Download a copy from Rocket Software.
If you are a user of IzODA, then there is a copy of bash
installed with the software. You can simply invoke it directly from the z/OS UNIX command prompt. For example, it might be mounted at /usr/lpp/IBM/izoda/anaconda/bin/bash
Alternatively, Rocket Software provides a port of bash to z/OS. You can download it at no charge at the Rocket Community, though you will have to register for a (free!) account for access. You will also need a copy of gzip
to decompress the bash tar file.
To download bash
and gzip
, do the following:
- Go to the Rocket Community site.
- Register for a new account if you don’t have one; otherwise, log in.
- Click “Downloads”.
- Select the “z/Opensource” category.
- Type “USSP-719” into the filter list.
- Click the ID link for Gzip that appears.
- Download the “z/OS Gzip 1.9 distribution” package. This is an uncompressed tar file.
- Close the download window, and type “USSP-711” into the filter list.
- Click the ID link for Bash that appears.
- Download the “z/OS Bash 4.3 distribution” tar.gz file.
How to Install Bash
Now that you have both files downloaded to your local machine, you need to upload them to z/OS. The simplest way to do this is using sftp
. Depending on what operating system you are using on your local machine, there are a variety of programs that provide sftp
support. Linux and macOS provide a built-in sftp client on the command line. Windows users can download the open-source WinSCP client instead.
Note: It is critical that you upload both files to z/OS using the sftp protocol. This is because z/OS will perform an ASCII->EBCDIC conversion to any files uploaded using scp. This conversion will mangle the tar files, making them unusable.
Here is an example using the Linux sftp
command to upload the files:
$ sftp pkstnp8.pok.stglabs.ibm.com
Connected to pkstnp8.pok.stglabs.ibm.com.
sftp> put bash-4.3_b018.170518.tar.gz
Uploading bash-4.3_b018.170518.tar.gz to /home/angio/bash-4.3_b018.170518.tar.gz
bash-4.3_b018.170518.tar.gz 100% 1098KB 1.4MB/s 00:00
sftp> put gzip-1.9-edc_b002.180703.tar
Uploading gzip-1.9-edc_b002.180703.tar to /home/angio/gzip-1.9-edc_b002.180703.tar
gzip-1.9-edc_b002.180703.tar 100% 1134KB 1.3MB/s 00:00
sftp> quit
Once the files are uploaded to your z/OS system, you need to log into z/OS UNIX. I prefer using ssh
, but you can also use the OMVS
interface from within ISPF. You then need to extract the files from the gzip tar file, and put the location into your PATH environment variable.
Here’s how to do it:
- Login to z/OS UNIX.
$ ssh pkstnp8.pok.stglabs.ibm.com
ANGIO@pkstnp8 ~>
- Create a directory that will hold the gzip and bash tools. This can be in your home directory, or anywhere else on the system that you have write access to. The instructions that come with tool suggest using the
/rsusr/rocket
directory, but this is not required.
$ mkdir ported
$ cd ported
- Extract the gzip files from the tar file they are distributed in.
$ tar -xof ~/gzip-1.9-edc_b002.180703.tar
$ ls
CHANGES.ZOS README.ZOS bin share README VERSION.ZOS man
- The executable
gzip
file is located in theported/bin
directory. For ease of use, this directory should be added to your PATH environment variable. This will allow you to invokegzip
without specifying the full pathname each time. To update the PATH, run the following command:
$ export PATH=~/ported/bin:$PATH
- You can now run the gzip command directly:
$ gzip
gzip: compressed data not written to a terminal. Use -f to force compression.
For help, type: gzip -h
- Note that this change to your PATH is only temporary, and will vanish when you log out from your shell session. To make it permanent, place the above
export
line in your shell profile. Just open the file~/.profile
with your favorite editor (vi
,oedit
, etc.) and paste that line in. - We can now use the
gzip
utility to decompress the bash tar.gz file, and pipe the output to thetar
utility to extract the files.
$ gunzip -c ~/bash-4.3_b018.170518.tar.gz | tar -xof -
- At this point, you can start the
bash
shell.
$ bash
- This is a great time to start experimenting with all the wonderful features of the bash shell as described in the first part of this article!
Setting the Default Shell
If you want to always use the bash shell, there are a few ways to accomplish that. Unlike Linux, there is no chsh
command to change the user’s shell. In addition, there is no /etc/passwd
file, so shell changes have to be performed via different methods. To do this:
- Use the RACF ALTUSER command from TSO. This allows you to directly set the shell that will be started when logging into z/OS UNIX. Note that you will need authorization to run this command, so you might want to contact your friendly system programmer.
ALTUSER USERNAME OMVS(PROGRAM('/path/to/bin/bash'))
- Edit the
/bin/sh
shell profile such that thebash
shell is invoked as the last step. In some cases, you want to run bash as an interactive shell, leaving/bin/sh
in place otherwise. The following code can be put at the end of your~/.profile
and will only runbash
during an interactive session, and if the file exists. (This code assumes thatbash
is in theported
directory within your home directory.)
tty > /dev/null
if (test $? -eq 0) then
if [ -f ~/ported/bin/bash ]
then
exec ~/ported/bin/bash
fi
fi