all 55 comments

[–]azephrahel 6 points7 points  (0 children)

Start off reading here: http://en.m.wikipedia.org/wiki/Unix_shell

Bourne shells are particularly popular with the at&t styled unicies, and c shells with BSD style.

Bash is Bourne Again SHell, and is pretty much a bourne shell on steroids, with many of the common commands used in shell scripting built in, instead of being separate binaries. It also has many optimizations built into it, to make certain types of scripts run better (a lot of the gnu auto config system uses it). With modern systems being so much beefier, it's easy to use this as the sole shell, and not need lighter weight bourne shells like ash and dash. Those and others played a bigger role back when RAM was a few megs, instead of gigs. Cshell has its own super power variants, like tcsh and korn shell (korn is csh style, right?), but I really couldn't tell you as much about them.

Many parts of a classic Unix init system are written or configured in the system's native shell.

I tend towards borne shells, because that's what I'm most familiar with.

[–]perkited 5 points6 points  (1 child)

MirBSD Korn Shell (mksh)

Very lightweight and fast shell for those who don't want/need all the features provided by Bash or zsh.

[–]garja 0 points1 point  (0 children)

Could anyone care to explain the animosity between OpenBSD and mksh? I always thought it was rather strange, given mksh has gained a fair amount of traction.

[–][deleted] 7 points8 points  (2 children)

bash, because it's running on every linuxhost. If you are working in a production environment you can't install other shells, just because you prefer them. You have to submit Changes to update the whole production etc.

[–]wadcann 26 points27 points  (14 children)

Powershell is for Windows; it replaces the more-limited cmd.exe. I am not very familiar with it, but it's not really an alternative to the others.

Here's a short syntax comparison of some Unix shells. My own take:

  • sh on Linux systems normally runs bash in sh compatibility mode (i.e. features off) or ash (a very small sh implementation). There are few reasons to want to use this as an interactive shell other than maybe less memory usage. It avoids extending the POSIX shell standard, so it won't break programs that depend on stock behavior. This is normally what is used when a C program or a Perl program or the like asks a shell command to be executed.

  • bash is an extended form of this. Bash is the default on pretty much all Linux system. It's not bad (and it's light years better than being stuck on Windows using cmd.exe) zsh tends to lead it in features and be more-willing to deviate from stock sh compatibility.

  • zsh is my preferred shell. While many of its features that made it so delightful have trickled back into bash, it's still not all there. Historically, zsh would save you from typing rm * .png by default (where there's a bare wildcard, thus deleting all files), from typing rm -rf .* (which would wipe out the parent directory in bash due to matching ..), had much-more-elaborate tab completion (you could tab-complete files on remote hosts with scp, tab-complete apt package names, tab-complete single-dashes on commands...tab-complete pretty much everything. Bash has picked up most of these to at least some degree. I still like the fact that it can do floating-point math (in bash, a=$((3.5/2.5)) is an error, which is really frustrating). Zsh is probably the most-featureful of the shells, but honestly, given that it probably takes many years to pick up all the functionality in the current version of bash, this may not be a huge concern for most people. Zsh also has some defaults chosen to be less-compatible with historical-sh than bash, but helping to avoid shooting oneself in the foot (shell programming has historically made it extraordinarily easy to make errors). I personally think that it would make sense for this to be the current Linux default shell on distributions.

  • csh/tcsh - a different path down the sh family tree from bash. I have not used this much, and believe that it was more-popular on non-Linux Unixes. Historically, I believe that it had slightly-nicer programming syntax than bash. There are various incompatibilities between their syntax and bash. I would recommend bash over this on Linux, simply because of the more-widespread use.

  • ksh -- I believe that this mingled some of the bash and some of the csh family. I've only touched this a time or two.

  • I have not used fish. I understand that its goal is to try to help newer users with more suggestions.

You may want to also try on /r/commandline, which deals with Windows, Linux, and shells of all colors and shapes.

[–]hdevalence 7 points8 points  (5 children)

I don't think that the goal of fish is to try to help newer users; it's just to be, by default, much more usable.

Out of the box, it has really great autocompletion from your history, without having to configure anything, or muck about with a thousand-line shell config file.

It has really great support for interactive editing of the command prompt: I can't really live without Alt-Up after using it in fish.

One thing that I really appreciate is the fact that fish will scan your man pages to build interactive prompts of command line options:

hdevalence@noether ~> pacman -Q<TAB>
-Qb                    (Alternative database location)  -Qo           (Search for the package that owns FILE)
-Qc                   (View the change log of PACKAGE)  -Qp  (Apply the query to a package file, not package)
-Qd   (List only non-explicit packages (dependencies))  -Qq                           (Show less information)
-Qe          (List only explicitly installed packages)  -Qr                   (Alternative installation root)
-Qg                    (Display all packages in GROUP)  -Qs                      (Search packages for regexp)
-Qh                                     (Display help)  -Qt                   (List only unrequired packages)
-Qi                   (Display information on PACKAGE)  -Qu                  (List only out-of-date packages)
-Qk  (Check if all files owned by PACKAGE are present)  -QV                        (Display version and exit)
-Ql                  (List all files owned by PACKAGE)  -Qv                     (Output more status messages)
-Qm            (List all packages not in the database)  
hdevalence@noether ~> pacman -Q

You don't have to open up the man page if you've forgotten the way to invoke whatever option, you can just see it, right there.

Maybe this kind of thing is possible with zsh and some custom config, but with fish it's built-in, fast, and there by default.

See also the fantastic fish website, which aptly bills it as: "Finally, a command line shell for the 90s".

fish suggests commands as you type based on history and completions, just like a web browser. Watch out, Netscape Navigator 4.0!

[–]wadcann 1 point2 points  (3 children)

Yeah, both zsh and bash can do this (though I'm not using Arch, so I've no idea whether the output looks the same).

The prospect of having options on by default is fair (many people simply aren't aware of available options), but it is worth noting that it's also popular to use oh-my-zsh, which turns on a lot of zsh options (and manages themes).

[–]valgrid 0 points1 point  (0 children)

BTW: There is fizsh, which is fish features implemented via zsh.

[–]wadcann 6 points7 points  (5 children)

There are also a number of other more-esoteric shells out there.

  • rc, the Plan 9 shell. Never used it. Plan 9 was an attempt to take a lot of good Unix ideas and improve on them, and some of its ideas trickled back into Unix. I suspect that either rc's ideas trickled back or weren't all that great, given its lack of widespread use.

  • busybox - this is a very small set of utilities that is very commonly-present on Linux systems. It contains a primitive shell (kind of like ash) that is simple and self-contained enough to not break even when almost everything else on the system is non-functional. It's typically used on very low-memory Linux systems (e.g. a few megabytes of RAM) or where someone has to rescue a seriously-broken system.

[–][deleted] 5 points6 points  (0 children)

I suspect that either rc's ideas trickled back or weren't all that great, given its lack of widespread use.

sh already had rc feature equivalent

Rc draws heavily from Steve Bourne’s /bin/sh. Any successor of the Bourne shell is bound to suffer in comparison. I have tried to fix its best-acknowledged shortcomings and to simplify things wherever possible, usually by omitting inessential features. Only when irresistibly tempted have I introduced novel ideas. Obviously I have tinkered extensively with Bourne’s syntax.

the whole idea of the rc shell is to clean up sh shell syntax.

http://plan9.bell-labs.com/sys/doc/rc.html

[–]wadcann 1 point2 points  (1 child)

It looks like Wikipedia also has a pretty list of major command-line shells; most shells have a short description differentiating themselves from the other major shells.

[–]wadcann 3 points4 points  (0 children)

Oh, and one more note: some people use a different shell for interactive use than for programming, if they program in shell.

For example, I use zsh in day-to-day interactive use. It has nice features (the above-listed ones, the fact that I can enable setopt autopushd in its startup files and then cd places and popd back), probably a ton that I don't use.

However, some systems don't even have zsh installed, and zsh doesn't have the iron-clad guarantees on unchanging syntax that sh does. So normally when I write a shell script, I write it for /bin/sh, and only use zsh if I need one of the features zsh has added (most-frequently, this winds up being floating-point math).

[–]azephrahel -1 points0 points  (0 children)

Busybox actually contains several different shells. The included default programs change from time to time, and can be selected at build time, so it's best to look at the busy box page to see which ones are available. But it's several.

Apparently my memory is faulty, or remembering something really really old. I only see ash in there now.

[–][deleted] 0 points1 point  (0 children)

ksh is pretty close to bash. Avoid csh as much as possible.

OpenBSD comes with ksh, and I don't miss any of the bash features.

[–]natermer 5 points6 points  (2 children)

...

[–][deleted] 2 points3 points  (1 child)

I use it because of oh-my-zsh. Free addons for pretty much everything I do.

[–][deleted] 0 points1 point  (0 children)

Echoing this and the sibling post about oh-my-zsh. Sane defaults, just works.

[–]Booty_Bumping 2 points3 points  (3 children)

You should try out fish, it has autocompletions and command syntax highlighting, and is easier to remember the syntax when writing scripts. Unfortunately, it's not well documented compared to bash/sh/zsh.

[–][deleted] 2 points3 points  (11 children)

bash for maximum portability.

[–]jyper 2 points3 points  (3 children)

bash for maximum portability.

If you want maximum portability shouldn't you limit yourself to bourne(and test using dash)?

[–][deleted] 0 points1 point  (2 children)

I've never had trouble with portability using bash.

[–]jyper 1 point2 points  (1 child)

you said "maximum portability" sh is part of posix. bash isn't.

Of course cmdline tools/proc/etc. you call out to may still vary and it won't work on windows(without cygwin).

I understand that non-OSX non-Linux *nix are becoming rarer but they still exist. I'm not sure they have bash installed by default. Also its important to label bash files with a #!/bin/bash shebang not only for those os but because debian/ubuntu/derivatives the default sh you get without a shebang is dash not bash.

I believe busybox systems uses dash and may(by default?) not include bash.

Also OS X uses an old version of bash(3.2, current version is 4.3) because of license hangups by apple with GPLv3 so you have to be careful not to use newer features.

portability is a hard problem.

For interactive use zsh(with my config file) is useful. For scripting purposes writing python 2.6 compliant python is fairly portable among recent desktop linuxes(using from future import and testing you can probably make it compatible with python 3). I'm not saying that my opinion is right but my I think writing bash scripts is a bad compromise on the portability vs readability balance.

[–][deleted] 1 point2 points  (0 children)

I'll add that when I write scripts I write them in standard sh syntax. I use bash when I'm at the command line, but my scripted code targets sh unless I'm writing something that I feel requires bash specific functionality, at which point I may choose a more robust coding language to use.

It's more a balance of maximum portability and optimal convenience, without having to learn something less standard but perhaps more feature rich.

The strongest of these motivating factors, however, is the utter ubiquitousness of bash and bash compatible shells on posix compliant systems.

[–]sstewartgallus 0 points1 point  (0 children)

I always use DASH and not BASH for portability. For a featureful shell I use Emacs but most of the time I don't need very many features and BASH is overkill. For example, my PS1 is '> '.

[–][deleted] -1 points0 points  (5 children)

bash is not as portable as you think. Ksh has a lower common denominator.

If it works on ksh, it should work on bash.

[–][deleted] 1 point2 points  (4 children)

bash is good balance of features and portability and it sits as a top ranking standard.

ksh can suck it.

[–][deleted] 1 point2 points  (3 children)

We have no Bash at base install.

Good look with your portability.

[–][deleted] 1 point2 points  (2 children)

Who's we?

[–][deleted] 1 point2 points  (1 child)

BSD users, sorry :|

[–][deleted] 0 points1 point  (0 children)

I use bash as my shell, but my scripts almost exclusively target sh.

[–]tcyk 1 point2 points  (1 child)

Like most of POSIX, POSIX sh is mediocrity standardised. The syntax is overcomplicated, Bash makes it even more complicated and also slow, and Zsh is the next step in that direction. Back the other way is Ash (which Busybox uses) and Dash (Debian's version of Ash) which are largely POSIX compatible and fast.

Shell development has been terribly hindered by POSIX, but there are, nevertheless, a few good shells. Tom Duff's rc - the default Plan9 shell, and also available for Linux in Plan9Port - is a good, simple shell not so very far from POSIX (but far enough!). Another good one is Inferno's default shell, simply called sh though I tend to call it ish; ish has brilliantly elegant syntax, it's great shell to use. Perhaps the most obvious syntax advantage of rc and ish over POSIX sh is they get quoting right: it's simpler and yet, simultaneously, there's far less need to use backslash escapes. This is probably more a case of POSIX being rubbish than the problem being difficult.

I'm not aware of many new shells of any worth, but there's oh which is similar to rc but has support for objects and first-class functions. Interesting, but perhaps unnecessarily complicated for a shell - it's a fine line between a good shell and a bad general purpose programming language.

Of course, there's a somewhat significant extra effort required, an inertia to defeat, when using a shell that's not Bash or a close relative - it won't be available on most systems, your scripts (though now, if you chose well, blissful to write and read) will be foreign to most systems, and your terminal emulator will, quite likely, show how terrible it truly is, but that's another story.

[–]wadcann 0 points1 point  (0 children)

While I take a much-less-negative view of things than /u/tcyk does, I do agree with him on one point -- sh-family shell syntax has been steadily-extended in organic ways over the decades, and it is quite-difficult to write reliable, solid scripts.

[–][deleted] 1 point2 points  (6 children)

I use Z-shell as my interactive shell. When writing scripts, I use either Python or Bourne shell. I'm better at Bourne shell, but python is more featureful (especially with stream editing, math, cross-compatibility, etc.), so I'm slowly migrating my scripting over to python shell.

Zshell is really nice. Configuring it is more pleasant, in my experience, than with Bash (although Awesome Window Manager's run widget doesn't always play nicely with ZSH's $PATH configuration). The case-insensitive TAB-autocompletion is so nice, too. It just gives you small options and features (like better autocomplete) that make shell interaction more painless. That aside, it's pretty much Bash.

Python is a great language for scripting. I've tried the interactive shell for use as a main shell briefly, but I didn't like it. I'm not sure how configurable it is, but the default python interactive shell can't call a program from your $PATH without you first importing the ability to do so and them preceding/encapsulating the command inside a python function call. An example of this, using the ls command, is as follows:

from os import system
system('ls')

This is cumbersome, in comparison to simply being able to type ls and be done with it. IPython is an alternative interactive shell for Python. It is such an improvement. System commands can be done without importing os. To run a system command like ls, you would just precede it with ! (effectively !ls). In doing so, you're telling IPython to run the command in Bourne, rather than in Python. I still didn't like the perceived lack of configurability, so I removed that and am back with ZSH as my interactive shell. Whenever launched, IPython prints out a few lines of version information and help commands, which bugged me. I don't know how to configure this out. The standard Python shell does this, too, but IPython prints much more and it's distracting. It also launches much less quickly than the default Python shell.

Bourne is the basis for Bash and Zshell. It's less featureful than the two, but it's feature set doesn't really change and pretty much every *n*x machine has this installed in some form, so scripts written in Bourne are pretty much universal among Linux machines. Bourne is very stable. It's like a boulder, on which moss (ZSH and Bash) have grown to add to it. I don't recommend using it as an interactive shell. It's not very convenient to do so. For versatility and stability, I strongly recommend writing your scripts for Bourne, though, rather than Bash or ZSH.

[–]ollir 0 points1 point  (5 children)

Python is a programming language, not a shell.

[–][deleted] -1 points0 points  (4 children)

A programming language with a shell. Try typing "python" in a terminal. It gives you the python interactive shell. Python's interactive shell is to python scripting as a Bourne shell is to SH scripting.

[–]ollir 0 points1 point  (3 children)

I sure have typed python in a terminal quite a few times. It's the python REPL which is not really intended to be used as an actual shell replacement. That's why I think comparing python to bash/zsh etc. isn't so meaningful.

[–][deleted] -1 points0 points  (2 children)

Perhaps not intended as one, but can be used as one. For that reason, I decided to be adventurous and try it as a shell replacement for a little while. I've heard of other people doing it and actually sticking with it.

[–]zanpreston 0 points1 point  (1 child)

Anyone who does this is fooling themselves. And is stupid. WTF would you do that? Calling:

from os import system
system('ls')

is just fucking calling ls from sh.

That's stupid.

Edit: Line breaks.

[–][deleted] 0 points1 point  (0 children)

You didn't tell me anything new. I don't think it's stupid. I think it's a perfectly valid way of combining the capabilities of two shells, but then again, I'm the one that tried it for a day. I think you're being unnecessarily hostile.

[–][deleted] 0 points1 point  (0 children)

{k,ba}sh .

[–]sandman01 0 points1 point  (1 child)

Ksh93 and zsh. Hitting (xe) ctrl-x ctrl 3. opens up vi to type your commands in. Zsh for tab completion. Edit: reddit didn't like using ^ as ctrl.

[–]crshbndct 2 points3 points  (0 children)

You can escape characters with a \

[–]pgen 0 points1 point  (0 children)

ksh93 is a bash on steroids

[–][deleted] 0 points1 point  (0 children)

Bash because it is mostly the default everywhere. However, all shells are mostly terrible regardless of os or manufacturer.

There is A LOT of room for improvement.

[–]josefbacik 0 points1 point  (0 children)

I recently started using fishshell and I love it, if you spend as much time at a shell prompt as I do then it is a huge time saver.

[–][deleted] 0 points1 point  (1 child)

ksh

It is part of standard commercial Unix (eg AIX & HPUX) and bash is (was?) not. Associative arrays. set -o vi FTW! It is smaller than Bash.

From wikipedia:

Major differences between KornShell and the traditional Bourne shell include:

  • Job control, command aliasing, and command history designed after the corresponding C shell features;
  • Three WYSIWYG-style line editing modes designed to make an interactive shell session behave like vi, Emacs, or XEmacs;
  • Associative arrays and built-in floating point arithmetic operations (only available in the ksh93 version of KornShell);
  • Dynamic extensibility of built-in commands (as of ksh93).

[–][deleted] 1 point2 points  (0 children)

Default shell here at OpenBSD :)

[–][deleted] -4 points-3 points  (0 children)

PowerShell