The easiest way by far is to use the same shell on both systems. Just because one shell is preinstalled (there's no such thing as a “default shell” for scripts, the shell is whatever the shebang line says) doesn't mean that you can't install others. You can install bash on AIX (from the toolbox, for example), or ksh93 for Linux (with your distribution's package manager: install the ksh
package).
If you pick ksh, beware that /usr/bin/ksh
on AIX is ksh88. There is no version of ksh88 for Linux, only ksh93, which is available as /usr/bin/ksh93
on AIX.
It is easier if the same shell is installed at the same location on both systems (a symbolic link is fine), so that you can use the same path in the shebang line. If having the same location is too difficult, you can use something like #!/usr/bin/env bash
, as long as you ensure that bash
is in the PATH
on both systems. This may be useful if you have to install bash or ksh in your home directory because you don't have root access.
If you really can't install the same shell on both machines — presumably because there's some silly compliance rule that only complicates people's life but is too entrenched to overturn — you have a few possibilities.
- Use
#!/bin/sh
as your shebang line and program in the intersection of what your systems offer. All modern unix systems provide a POSIX shell as /bin/sh
. On AIX, /bin/sh
is ksh88. On Red Hat, /bin/sh
is bash (which behaves slightly differently when invoked as sh
). Beware that on some other operating systems (for example, on many Linux distributions), /bin/sh
is a smaller shell which may not have much more than POSIX features.
Start your scripts with some boilerplate code that looks for a better shell and executes it.
#!/bin/sh
if [ -n "$BASH" ]; then
… bash compatibility code …
elif type whence >/dev/null 2>/dev/null; then
… ksh compatibility code …
elif type ksh93 >/dev/null 2>/dev/null; then
exec ksh93 "$0" "$@"
elif type ksh >/dev/null 2>/dev/null; then
exec ksh "$0" "$@"
elif type mksh >/dev/null 2>/dev/null; then
exec mksh "$0" "$@"
elif type bash >/dev/null 2>/dev/null; then
exec bash "$0" "$@"
else
echo 1>&2 "Cannot find ksh or bash, aborting"
exit 125
fi
In either case, the intersection of ksh88 and bash provides some useful features beyond POSIX, but you may need a little compatibility code. In particular:
- Array assignment in ksh88 uses
set -A
. See assignation variable under different ksh environment
- Local variables are declared by
typeset
.
- Ksh88 doesn't have
${VAR/PATTERN/REPLACEMENT}
, $'…'
or FIGNORE
. It does have [[ … ]]
.
- To enable
@(…)
and other ksh extended patterns in bash, run shopt -s extglob
.
AIX commands
andLinux commands
are very similar, it may make sense to put them in the same script with some extra code to handle the differences. IfAIX commands
andLinux commands
are completely different, it may make more sense to have two different versions of the script. – jw013 Aug 5 at 20:16