Bash or KornShell (ksh)?

115,111

Solution 1

Bash.

The various UNIX and Linux implementations have various different source level implementations of ksh, some of which are real ksh, some of which are pdksh implementations and some of which are just symlinks to some other shell that has a "ksh" personality. This can lead to weird differences in execution behavior.

At least with bash you can be sure that it's a single code base, and all you need worry about is what (usually minimum) version of bash is installed. Having done a lot of scripting on pretty much every modern (and not-so-modern) UNIX, programming to bash is more reliably consistent in my experience.

Solution 2

The difference between Kornshell and Bash are minimal. There are certain advantages one has over the other, but the differences are tiny:

  • BASH is much easier to set a prompt that displays the current directory. To do the same in Kornshell is hackish.
  • Kornshell has associative arrays and BASH doesn't. Now, the last time I used Associative arrays was... Let me think... Never.
  • Kornshell handles loop syntax a bit better. You can usually set a value in a Kornshell loop and have it available after the loop.
  • Bash handles getting exit codes from pipes in a cleaner way.
  • Kornshell has the print command which is way better than the echo command.
  • Bash has tab completions. In older versions
  • Kornshell has the r history command that allows me to quickly rerun older commands.
  • Kornshell has the syntax cd old new which replaces old with new in your directory and CDs over there. It's convenient when you have are in a directory called /foo/bar/barfoo/one/bar/bar/foo/bar and you need to cd to /foo/bar/barfoo/two/bar/bar/foo/bar In Kornshell, you can simply do cd one two and be done with it. In BASH, you'd have to cd ../../../../../two/bar/bar/foo/bar.

I'm an old Kornshell guy because I learned Unix in the 1990s, and that was the shell of choice back then. I can use Bash, but I get frustrated by it at times because in habit I use some minor feature that Kornshell has that BASH doesn't and it doesn't work. So, whenever possible, I set Kornshell as my default.

However, I am going to tell you to learn BASH. Bash is now implemented on most Unix systems as well as on Linux, and there are simply more resources available for learning BASH and getting help than Kornshell. If you need to do something exotic in BASH, you can go on Stackoverflow, post your question, and you'll get a dozen answers in a few minutes -- and some of them will even be correct!.

If you have a Kornshell question and post it on Stackoverflow, you'll have to wait for some old past their prime hacker like me wake up from his nap before you get an answer. And, forget getting any response if they're serving pudding up in the old age home that day.

BASH is simply the shell of choice now, so if you've got to learn something, might as well go with what is popular.

Solution 3

I'm a korn-shell veteran, so know that I speak from that perspective.

However, I have been comfortable with Bourne shell, ksh88, and ksh93, and for the most I know which features are supported in which. (I should skip ksh88 here, as it's not widely distributed anymore.)

For interactive use, take whatever fits your need. Experiment. I like being able to use the same shell for interactive use and for programming.

I went from ksh88 on SVR2 to tcsh, to ksh88sun (which added significant internationalisation support) and ksh93. I tried bash, and hated it because it flattened my history. Then I discovered shopt -s lithist and all was well. (The lithist option assures that newlines are preserved in your command history.)

For shell programming, I'd seriously recommend ksh93 if you want a consistent programming language, good POSIX conformance, and good performance, as many common unix commands can be available as builtin functions.

If you want portability use at least both. And make sure you have a good test suite.

There are many subtle differences between shells. Consider for example reading from a pipe:

b=42 && echo one two three four |
    read a b junk && echo $b

This will produce different results in different shells. The korn-shell runs pipelines from back to front; the last element in the pipeline runs in the current process. Bash did not support this useful behaviour until v4.x, and even then, it's not the default.

Another example illustrating consistency: The echo command itself, which was made obsolete by the split between BSD and SYSV unix, and each introduced their own convention for not printing newlines (and other behaviour). The result of this can still be seen in many 'configure' scripts.

Ksh took a radical approach to that - and introduced the print command, which actually supports both methods (the -n option from BSD, and the trailing \c special character from SYSV)

However, for serious systems programming I'd recommend something other than a shell, like python, perl. Or take it a step further, and use a platform like puppet - which allows you to watch and correct the state of whole clusters of systems, with good auditing.

Shell programming is like swimming in uncharted waters, or worse.

Programming in any language requires familiarity with its syntax, its interfaces and behaviour. Shell programming isn't any different.

Solution 4

This is a bit of a Unix vs Linux battle. Most if not all Linux distributions have bash installed and ksh optional. Most Unix systems, like Solaris, AIX and HPUX have ksh as default.

Personally I always use ksh, I love the vi completion and I pretty much use Solaris for everything.

Solution 5

I don't have experience with ksh, but I have used both bash and zsh. I prefer zsh over bash because of its support for very powerful file globbing, variable expansion modifiers, and faster tab completion.

Here's a quick intro: http://friedcpu.wordpress.com/2007/07/24/zsh-the-last-shell-youll-ever-need/

Share:
115,111
Admin
Author by

Admin

Updated on February 21, 2020

Comments

  • Admin
    Admin over 4 years

    I am not new to *nix, however lately I have been spending a lot of time at the prompt. My question is what are the advantages of using KornShell (ksh) or Bash Shell? Where are the pitfalls of using one over the other?

    Looking to understand from the perspective of a user, rather than purely scripting.

  • Admin
    Admin over 15 years
    ksh has completion, just not with the tab key.
  • Jon Ericson
    Jon Ericson over 15 years
    I'd say bash is a standard. ;-)
  • Hank Gay
    Hank Gay over 15 years
    bash is only the standard for Linux. The original Bourne shell (sh) is the standard for cross-platform scripts.
  • Stan Graves
    Stan Graves almost 15 years
    Posix-sh is (or perhaps 'should be') the standard for cross platform scripting.
  • Stan Graves
    Stan Graves almost 15 years
    If you are planning to distribute scripts use posix-sh. Bash is a good shell, and the default on linux. Older Unix flavors tend to have sh, ksh, and csh. In a production environment, it can be difficult to get permission or forgiveness for installing the shell of your choice on all the systems.
  • Stan Graves
    Stan Graves almost 15 years
    HP-UX provides sh, csh, and ksh as default shells. In 11.31 bash was included on the default installation media. But, given the amount of 10.20 still running in the world, ksh is still a better bet for administering HP-UX.
  • SourceSeeker
    SourceSeeker over 14 years
    ksh --version: "version sh (AT&T Research) 93t+ 2009-05-01" has tab-completion and Esc-completion.
  • Katerberg
    Katerberg over 13 years
    By default, ksh uses <ESC><ESC> as their completion in case anyone was curious. Source: kornshell.com/doc/faq.html
  • Matthieu
    Matthieu over 13 years
    Corrected: Bash is the standard for Linux.
  • glenn jackman
    glenn jackman about 13 years
    Note that bash has different behaviour if /bin/sh is (sym)linked to bash: If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.
  • Brian Warshaw
    Brian Warshaw almost 13 years
    It's not installed by default on the AIX we use at work (major US financial institution), and boy do I wish it was.
  • chepner
    chepner over 12 years
    For the sake of completeness, bash version 4 supports associative arrays. I've never used AAs in either shell, so I can't say if they work better, as well as, or worse than Kornshell's implementation.
  • amphibient
    amphibient over 11 years
    what do you mean by "interactive use"?
  • amphibient
    amphibient over 11 years
    by "interactive use" do you mean manual prompt-to-prompt command execution as opposed to running scripts that bundle such commands?
  • amphibient
    amphibient over 11 years
    "You can usually set a value in a Kornshell loop and have it available after the loop." -- i find that confusing as hell. i certainly support that a variable should have the scope only within its level of nesting and not outside of it.
  • David W.
    David W. over 11 years
    It has to do with piping a command to a while readloop. Kornshell has no problems with accessing the variable outside the loop. However, for BASH, that pipe is a child process, and you lose the value once the loop is done. There are ways to get around this.
  • Jon Ericson
    Jon Ericson over 11 years
    @foampile: When you are typing into a terminal command line. ;-)
  • amphibient
    amphibient over 11 years
    i thought so. thanks
  • Telemachus
    Telemachus about 11 years
    @foampile Yes, that's what "interactive use" means.
  • Dmytro Sirenko
    Dmytro Sirenko almost 11 years
    Also, bash implements cd old new as ^old^new and can do this not only on directories/
  • David W.
    David W. almost 11 years
    @EarlGray That doesn't work unless the previous command was my change directory. Someone else pointed out I could do this $ cd ${PWD/foo/bar} but that's a bit long to type.
  • Dave
    Dave almost 11 years
    In Bash you can rerun history commands by typing in !N where N is the line number.
  • David W.
    David W. almost 11 years
    @Dave It's not as convenient as r vi where it will run my last VI command. I usually don't know the history line number, and I usually set extglob (a feature that's on by default in Ksh and I heavily depend upon) which kills the use of ! in command history.
  • David W.
    David W. almost 11 years
    Just want to add, all the Kornshellisms I mentioned are nice to have features I've grown dependent upon. If I learned shell today, it would be BASH, and wouldn't understand all the whining by the Kornshell old timers talking about this or that feature and how much better the Internet was back in the old days. It would be like listening to your grandpa whine about how much better things were when he was a kid. Come to think it it, it is your grandpa whining about how much better things were when he was a kid. (When I was a kid, there were only three TV channels, and we liked it!)
  • thom
    thom over 10 years
    On Debian the standard /bin/sh is actually dash, the debian almquist shell. This takes a lot of people by surpise when their "valid" bash commands are rejected by #!/bin/sh
  • thom
    thom over 10 years
    On Debian the standard /bin/sh is actually dash.
  • Walter A
    Walter A over 9 years
    ^Rvi (without space) reruns vim. Vim ?! Use :color desert in .vimrc when you have :syntax on.
  • Wildcard
    Wildcard over 8 years
    In bash, !vi will run the last run command that started with the letters 'vi'. If you're not sure if that command was the one you want, use !vi:p which will print the command and add it to your history list newly—but not actually run it. Then if it is what you want, a simple up arrow-enter, or just !! to run it. See man bash and search for HISTORY EXPANSION.
  • Wildcard
    Wildcard over 8 years
    You can use vi completion in bash with set -o vi, and add it to your ~/.bashrc file to make it persistent. That's how I have mine set.
  • Wildcard
    Wildcard over 8 years
    I also think it's important when learning bash to keep very clear track of which options are bash-specific and which are POSIX compatible, and try to make the POSIX compatible approaches your habit. If you use bash-only features you should know you are using them. Keeping them mentally separate from the beginning is a very good idea.
  • Charles Duffy
    Charles Duffy over 7 years
    Much of this is outdated. bash has had associative arrays since 4.0 (and they're hugely useful -- would you try programming in Python without dicts?), and namevars since 4.3. On the other hand, genuine David Korn ksh93 still has a huge edge in performance -- things one needs to use awk for for pure performance reasons in bash (think about textual transformations or analysis of a multi-GB stream) can be done in ksh93 natively with comparable speed.
  • Charles Duffy
    Charles Duffy over 7 years
    As of this answer's writing, ksh93 arguably had more bells and whistles from a programming perspective (associative arrays and namevars come first to mind) -- though that's changed in the intervening eight years. It still has floating-point math, which bash continues to lack.
  • Charles Duffy
    Charles Duffy over 7 years
    Oh -- and ksh93 has floating-point math, which bash still lacks.
  • Charles Duffy
    Charles Duffy over 7 years
    If you're doing only minimum-common-denominator ksh, I'd agree. Genuine David Korn ksh93, on the other hand, has compelling advantages for scripting: Speed that puts it near awk for text processing; native floating point math; namevars and associative arrays even on systems not running the latest release; etc.
  • Charles Duffy
    Charles Duffy over 7 years
    Re: your read difference, in noninteractive mode that's actually configurable for modern bash -- see the lastpipe option.
  • Henk Langeveld
    Henk Langeveld over 7 years
    @CharlesDuffy correct, and it was available when I wrote this - however, it's still not default behaviour - you need bash 4.2 or 4.3 and the lastpipe shopt. Shopt options are awkward, as their setting can actually trigger syntax errors.
  • Jerfov2
    Jerfov2 over 7 years
    About the 5th point, you can simply do alias print=echo
  • niels
    niels over 6 years
    Thanks for this answer, it made me laugh :D (and was useful)
  • Jethro Cao
    Jethro Cao about 3 years
    in bash, $ cd - takes you to your $OLDPWD
  • Kajukenbo
    Kajukenbo over 2 years
    Sorry, but Bash is NOT "installed on every *nix out there". Although it is probably on every GNU/Linux distro. If you are supporting UNIX or you want to follow POSIX then learn & use ksh, because ksh88 was (in part) what the sh standard was based on. If you are only on GNU/Linux and don't care about compatibility with legacy systems then Bash is fine. Most of the features are comparable between the two, but Bash makes it too easy to violate POSIX for my taste. Even when you tell it specifically not to, it usually lets you anyway. The vi mode in Bash is also pretty poorly implemented.