I kept seeing odd error messages from my shell script that simply made no sense. No matter what changes I made a new error seemed to pop up. A short while later I did notice at the top of the script that it was using a korn shell interpreter.
This was not as helpful as you might initially guess. Sure there are differences between the two shells but most of the scripts that I write would work under either. Besides, I had a small script with the new code I wanted to test and it worked fine under both the bash and korn shell.
I didn’t initially consider that the the script itself wasn’t not being run in the same manner by the calling system as by me.
In the end I wanted to determine if the shell was the same as what I had selected – after all how could it not be my shell.
The most straight forward method would be to see which shell is interpreting. It is just as easy as checking which process or processes are running. Just to see which programs, in this case our shell, is running I ran the process status command (ps).
Nothing else is really running in my Korn shell example. The only two processes is the korn shell and the ps command. The Korn shell is not really all that surprising as this is a terminal window for my user and the Korn shell was the shell setup for in the /etc/passwd file.
> ps -f UID PID PPID C STIME TTY TIME CMD fkadm 3819 3816 0 14:52:41 pts/2 0:00 -ksh fkadm 4609 3819 0 14:54:37 pts/2 0:00 ps -f
It is almost the exact same story for the Bash shell. My user was started with a Korn shell and (process 23509) and then ran the Bash shell (process 23541). The ps command is then run from the Bash shell reporting on anything that is running.
> ps -f UID PID PPID C STIME TTY TIME CMD fkbin 23509 23507 0 10:27:31 pts/4 0:00 -ksh fkbin 23541 23509 0 10:27:31 pts/4 0:00 bash fkbin 4128 23541 0 14:53:51 pts/4 0:00 ps -f
The starting point for my finding my shell is to know which of the many processes to look at. The good news is that I am able to get my process id using the special shell variable “$$”.
Everything from that point is pretty straight forward. We can use the -p and -o arguments with the ps command to see specific values for a specific process.
process status (ps)
|-p||process id||selects process status from list where the process id matches this value.|
|-o||format||The format is one of many possible fields that can be selected from the process status. There are quite a few possibilities, but the ones that stood out as the most immediately interesting are as follows.
The first six should look familiar as these are the values that are output when doing a full listing (-f). The comm format is the actual command which in this case is the interpreter while the args is both the command and its arguments.
With this little bit of knowledge I had enough information to query what interpreter was running my script.
#!/usr/bin/bash MYPID=$$ MYSHELL=`ps -p $MYPID -o comm | egrep -v "CMD|COMMAND"` MYCOMMAND=`ps -p $MYPID -o args | egrep -v "CMD|COMMAND"` echo the shell for process id $MYPID is $MYSHELL. echo the entire command is $MYCOMMAND
This type of shell goodness should be all that it takes to find out more about how you are being called. I was a bit surprised to see that my script was being called with a different shell altogether.
The shell calling my program was /usr/bin/sh which is a lot less compatible with either the Korn or Bash shell. A bit more digging and I found out that the script was being passed directly to the shell interpreter. This explains why the Korn shell wasn’t being used.
Well, I guess this is proof that you cannot always trust IT.