5

I researched a lot of documentation online and tried to compare ksh to bash, as we want to refactor our scripts from ksh to bash. After a lot of researching I couldn't find any ksh syntax, which is not compatible with bash.

I found some articles like https://www.baeldung.com/linux/korn-vs-bash, where some differences are pointed out, but every syntax, like double braces, which should not work on ksh, worked in both shells.

Is it correct to assume that all scripts written in ksh syntax are also valid in bash?

3

2 Answers 2

6

Not all ksh scripts will run in Bash. Bash has "borrowed" a few features that originated from ksh, but it doesn't support everything ksh(93) has.

The most obvious difference is in the handling of local variables: ksh's function foo functions support static scoping, while Bash supports dynamic scoping. Even though Bash supports the same style of function declarations, and ksh's typeset command, they're not compatible.

The following script runs in both, but behaves differently:

% cat local.sh
function g {
    echo "in g: '$var'"
}
function f {
    typeset var="value from f"
    echo "in f: '$var'"
    g
}
typeset var="value from main"
f
echo "in main: '$var'"

in ksh, function g sees the value set in the main level, while in Bash, it sees the value set in function f:

% ksh local.sh
in f: 'value from f'
in g: 'value from main'
in main: 'value from main'

% bash local.sh
in f: 'value from f'
in g: 'value from f'
in main: 'value from main'

With foo() functions, ksh's typeset would just modify the global value. Zsh and many other shells behave just like Bash, here. (Though they might only support local and not typeset. Ksh doesn't have local.)

Another thing is that ksh supports nested arrays (and IIRC, some other data structures too). Bash doesn't, and will just croak for e.g. this script:

% cat nested.sh
a=((a b c) (d e f))
typeset -p a
echo "a[1][*] is '${a[1][*]}'"
echo "a[1][2] is '${a[1][2]}'"

% ksh nested.sh
typeset -a a=((a b c) (d e f) )
a[1][*] is 'd e f'
a[1][2] is 'f'

There may be other, minor differences, like read -A vs. read -a for reading in an array, and ksh doesn't have Bash's mapfile/readarray (at least not with the same name). Of course Bash also has a few Bash-specific features, like all the BASH* variables.

(The above scripts were run with the ksh on my Mac, where ksh --version says sh (AT&T Research) 93u+ 2012-08-01)

3
  • 2
    Another difference: ksh supports extended glob syntax by default, but in bash you have to enable it with shopt -s extglob (and of course, ksh doesn't have shopt). Commented Aug 6 at 5:32
  • Great comparison, thanks! This helps finding the parts to be refactored.
    – Eriko
    Commented Aug 7 at 9:26
  • 1
    @Eriko, note that I can't remember if there are other, minor ones, so test carefully! The one about local variables is the biggest difference IMO, since it's likely a rather commonly used feature but one where ksh is quite different from anything else.
    – ilkkachu
    Commented Aug 7 at 9:44
2

In my experience, all scripts written in ksh will work in bash. There are some edge cases, like hash and alias, but you're unlikely to encounter those.

The other way round, executing bash scripts in ksh may be more challenging.

The fact that it works does not mean that the ksh syntax is best practice in bash.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .