Tech Tip: Be Like a Turtle!
Jesse Gorzinski talks about the shell that you use when connecting to IBM i with the Secure Shell (SSH) protocol.
By Jesse Gorzinski08/10/2017
The poet Bill Copeland once wrote “Try to be like the turtle—at ease in your own shell.” I find this to be great advice! Of course, I’m thinking of a different kind of “shell.” That is, I’d like to talk about the shell that you use when connecting to IBM i with the Secure Shell (SSH) protocol. It’s an important tool and one that you should strive to be “at ease” with. Did you know you have several options for which shell to use? Today, I’d like to discuss those options and highlight a new feature that lets you choose what’s best.
Fundamentals: What is a “Shell”?
Especially in the open source world, people talk about shells a lot. Instructions to “run this command in a shell” are standard fare. But, what is a shell? Simply put, a shell is a command processor. It is a program that takes input from the user and runs the appropriate commands. Conceptually, it is much like the CL entry screen you’ve used in 5250. Rather than running CL commands from the QSYS.LIB filesystem, it runs executable binaries from a hierarchical file system (stream files from the QOpenSys or root filesystems on IBM i). This includes things like open source language runtimes, common shell commands (ls, cd, pwd, cp), or any PASE executable (most open source). The best way to access a shell on IBM i is from an SSH client.
Shells also have their own language that’s used for defining sequences of commands, doing process control, and allowing for program logic, loops, etc. This language can often be invoked from the command line or placed in a source file, known as a shell script (a term you’ve likely heard before).
On IBM i, there are a number of shells available. Some of them, like the classic and popular QSHELL, are ILE programs. For today’s discussion, however, we need to focus solely on PASE shells, since the SSH server runs in PASE. Here’s a list of shells that are installed with PASE:
- /QOpenSys/usr/bin/bsh, known as the “Bourne Shell.” This is the default shell used by SSH sessions and was a common shell in many UNIX environments for years.
- /QOpenSys/usr/bin/csh, an alternative shell designed to have similarity to the C programming language
- /QOpenSys/usr/bin/ksh, known as “KornShell.” This is a derivative of the Bourne Shell, but with some added features.
- /QOpenSys/usr/bin/qsh, a PASE version of the classic QSHELL
- /QOpenSys/usr/bin/sh, which is just a symbolic link to the KornShell
Also, 5733-OPS ships bash in product option 7. This shell is inspired by the Bourne Shell. When installed, this shell can be found alongside other 5733-OPS tools at /QOpenSys/QIBM/ProdData/OPS/tools/bin/bash. It is often called the “Bourne Again SHell," (yes, there’s some humor there).
Choosing a Shell
So, at least a half dozen PASE shells are available from PASE or 5733-OPS. More are also available from the open source community. Choosing the right shell might seem like a daunting task. After all, each shell has its own set of usability and language features. I encourage you to research and find one that works best for you.
If you’d rather just trust me, I can give my recommendation. The bash shell is incredibly usable, flexible, and powerful. It has become very popular in the computing community. It is the default shell on most Linux distributions, macOS/Mac OS X, the Cygwin project, and the Linux Subsystem for Windows. Stay tuned for my next blog post, where I’ll talk about a few great bash features!
Setting Your Shell
The Bourne Shell (bsh) has been the default SSH shell on IBM i for years. In 2012, we added the ability for the default shell to be changed. This system-wide setting was done via a special configuration file keyword for OpenSSH. Today, however, I’m putting a spotlight on a newer and more sophisticated option. Now, you can customize the default shell on a per-user basis!
Of course, it requires you to have the proper PTFs installed. Here are the specific requirements
- IBM i 7.1: MF63567, SI63978, SI63981, and SI63982
- IBM i 7.2: MF63566, SI63977, and SI63980
- IBM i 7.3: MF63565, SI63976, and SI63979
What do these PTFs give you? The ability to set and query default shells via SQL. You can assign a user’s shell via the new QSYS2.SET_PASE_SHELL_INFO procedure. It takes two arguments, which you could probably guess. The first argument specifies the user, and the second specifies the shell. You can set a shell for other users, so long as you have *SECADM special authority and *OBJMGT and *USE authority to their user profile. Here’s a simple example, choosing bash:
call qsys2.set_pase_shell_info('OTHRUSR', '/QOpenSys/QIBM/ProdData/OPS/tools/bin/bash');
It also allows special value ‘*CURRENT’, so it’s easy to set your own shell:
call qsys2.set_pase_shell_info('*CURRENT', '/QOpenSys/QIBM/ProdData/OPS/tools/bin/bash');
You can also set a system-wide default shell, which will be used for any user that does not have a shell explicitly set. This requires *SECADM special authority and *OBJMGT and *USE authority to the QSYS user profile. Just specify ‘*DEFAULT’ for the user:
call qsys2.set_pase_shell_info('*DEFAULT', '/QOpenSys/QIBM/ProdData/OPS/tools/bin/bash');
We’ve also delivered the ability to query this setting, by way of a new PASE_SHELL_PATH column returned by the QSYS2.USER_INFO catalog
So to query if a shell has been set for your user profile:
select pase_shell_path from qsys2.user_info where authorization_name = user;
…or query which users have shells set:
select authorization_name, pase_shell_path from qsys2.user_info where pase_shell_path is not null;
You can also check to see if a system-wide default shell is set. To do so, just query the attribute from the QSYS user profile (it will be null if no default is set):
select pase_shell_path from qsys2.user_info where authorization_name = 'QSYS';
So, you can set and query a shell on a per-user basis or on a system-wide basis. To clarify, this is the shell selection behavior when an SSH session is started:
- If a user default shell is set, it is used regardless of whether a system-wide default is set.
- If the user’s default shell is not set, but a system-wide default is set, the system-wide default will be used.
- If neither a user default nor a system-wide default is set, /QOpenSys/usr/bin/bsh will be used.
Let’s walk through an example. My tool of choice? The Run SQL Scripts tool from IBM i Access Client Solutions, of course! First thing I want to do is check to see who has customized their shell:
Since no rows were returned, I know that no shell customizations have been done. In this case, each user will get the default bsh (Bourne Shell). But let’s say I’d like everyone to use bash instead. All I need to do is call set_pase_shell_info() with the ‘*DEFAULT’ user. I can then query for customizations to immediately see the change (remember, the value for the QSYS user contains the system-wide default):
At this point, every user would get bash as he or she connects with SSH. But wait a second: I have a user (JOE) who likes good old bsh. Well, I can do that, too!
So, at this point, all users will get bash except for JOE, who will get bsh.
Today’s tip is geared toward the SSH user. If you don’t use SSH, I have two things to say to you: First, thanks for reading this far! Second, please watch for my next blog post; I’ll try my hardest to convince you to do so! SSH is a powerful and secure way to access IBM i, and it’s now easy to choose your favorite shell and get comfortable with it.
Jesse Gorzinski is the business architect of open source technologies.
See more by Jesse Gorzinski