How can I write a script that is shell independent? I want to be able to run one script which will run in ksh, sh and bash.

For example: If I have a line in my script like whence ls which will run in ksh and not in sh, I want to be able to have something like

if (ksh)
then whence ls
if (sh)
then whereis ls

Can I use $SHELL value or is there any other way?

  • 1
    also note that whatever works in sh generally automagically works on "improved" shells like bash and ksh, because it's generally the least common denominator with regards to shell features. the only time you'll really run into trouble with major incompatibilities is if you try to make it run in the csh family. – strugee Aug 23 '13 at 21:29
  • 3
    While I'm sure such portability is achievable, I believe it's non-trivial to implement. I think you're better off using Perl or Python or similar. – Joseph R. Aug 23 '13 at 22:25

A pattern you'll typically see with Unix shell scripts is the use of a variable for the executables named by their generic function, for example $ECHO. You'll then have a top level function or two that will determine what $ECHO should be set to.

Once $ECHO has been set, then throughout your code you'll see this:

$ECHO "hi"

This saves you from having to litter your code with lots of if..then..else blocks which have nothing to do with your scripts functionality and only the platform interpreter that it's using.

So you could do the same for any key programs that you're interested in swapping out based on which interpreter/platform you're running on.

if (ksh)
else if (sh)

Should you do this?

I would say if you're trying to make your script portable and you're concerned with the availability of certain interpreters or executables it's best to code to the lowest common denominator, i.e. /bin/sh.

Just look at how Oracle and others do this. They generally provide their installers so that they're scripted in /bin/sh. This is the lowest common denominator when you get into supporting across a variety of Unixes such as Solaris, AIX, and Linux.

Take a look at this guide put together by Novell titled: Making Scripts Portable. It covers the lineage of the various shells and what the common set of commands are across several of them with tips on how to deal with their subtleties.

  • 1
    +1 Indeed. I believe this pattern is idiomatic in Makefiles especially. – Joseph R. Aug 23 '13 at 22:28

you might have to accomplish by kicking off another shell process like so ...

if [ -x /bin/ksh ]
    output=`/bin/ksh whence ls`

if [ -x /bin/sh ]
    output=`/bin/sh which ls`
  • 1
    What if all these shells exist? I think you're better off using an if...elif...else cascade. – Joseph R. Aug 23 '13 at 22:14
  • Besides, are we sure the if statement syntax itself will work on all shells? – Joseph R. Aug 23 '13 at 22:26
  • why would if ... elif ... else be better? Maybe the OP's intent is to see if whence and which yield different results or wants to do something else entirely. your are making assumptions about what the OP wants to accomplish. – Red Cricket Aug 24 '13 at 0:02
  • I believe that when you say "Maybe the OP's intent is..." you have fallen into the trap of making an assumption yourself, in which case you should mention it in the answer. As to why I believe my assumption is better, it's because of Occam's Razor. – Joseph R. Aug 24 '13 at 0:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.