Forgot your password?
typodupeerror
Linux Software

A Real Bourne Shell for Linux? 388

Posted by Cliff
from the is-bash-really-all-that-different dept.
the_code_poet asks: "I'm a lead developer for a software development company, and one of my responsibilities has been writing an installer for our product (of which Linux is one of the platforms). In keeping with UNIX tradition, the installer is written in shell (thats /bin/sh), but as many of you know there is no Bourne shell for Linux - only bash. This has caused inconsistencies (mostly bugs in bash) when writing a generic UNIX sh script that works fine on commerical *NIX's." For a semi-complete list of differences between bash and sh, you will want to check out section C1 of the Bourne Again Shell FAQ. To be honest, I have yet to run into much trouble with a script starting with #!/bin/sh with /bin/bash, and I've been using the latter for years. If any of you have had problems related to this, please tell us what the problem was and how you solved it. Also: would anyone out there be interested in writing a real Bourne Shell for Linux?

"On every distro I've ever seen /bin/sh is just a soft link to /bin/bash. If bash is invoked with sh as its name (argv[0]) then its supposed to act like Bourne - but that just doesnt happen (for example: export FOO=bar is *not* valid Bourne shell syntax, you must say FOO=bar; export FOO)

Do you think that the startup scripts for most distributions would break because, even though they say
#!/bin/sh at the top, they REALLY mean #!/bin/bash?

Given that there is no real Bourne shell for Linux, and that bash has an exhorbitant file size. Quoting bash's man page, here: '...it's too big and too slow' for something that is to be used as the defacto-standard shell for scripting, do you think its a worthy venture to set out to write a small, tight, pure Bourne shell?

*asbestos disclaimer*: This has nothing to with Bash as an interactive user shell and has nothing to do with a holy war over who's favorite shell is better than whomever's."

While doing a small bit of research on this question, I noted there was another Bourn-compatible shell out there called "ash", yet it's billed as doing "some things better and some things worse than bash". Does anyone use it, and find it better than bash for their shell scripting needs?

This discussion has been archived. No new comments can be posted.

A Real Bourne Shell for Linux?

Comments Filter:
  • Easy. (Score:5, Informative)

    by Flarners (458839) on Saturday November 17, 2001 @07:38PM (#2579683) Journal
    1. Download FreeBSD source.
    2. cd /usr/src/bin/sh; make; make install
    AFAIK the BSD Bourne shell is more or less the same as the real Bourne shell.
    • Re:Easy. (Score:2, Informative)

      by bwulf (325)
      4.4BSD-Lite (and derivatives) /bin/sh is Ash.

      Also, recent FreeBSD 4.x releases have replaced 4.4BSD csh with tcsh (original csh being available as a port).
    • Re:Easy. (Score:2, Interesting)

      by prog-guru (129751)
      Would this compile? I tried building the FreeBSD telnetd source on other systems when the telnetd exploit came out, and it wouldn't build.

      FreeBSD seems to favor csh anyway, root's shell is csh, they say don't every never change root's shell or your scripts will break (although they are sh scripts), bash is not installed in the base system, the package manager installs it in /usr/local, and bash 1.x isn't statically linked, so you can't use it in single user mode (bash 2.x is).

      I still prefer bash, despite FreeBSD's objections :)
      • Who says don't change root's shell? Not the FreeBSD Project ... in five years of using FreeBSD, I haven't found a single thing that breaks when root's shell changes.
  • by Z4rd0Z (211373) <joseph at mammalia dot net> on Saturday November 17, 2001 @07:40PM (#2579689) Homepage
    Starting your scripts with #!/bin/bash shows that you live in a Linux-centric world. No other OS puts bash under /bin. Since there's normally a link from bash to sh, it really makes sense for compatibility reasons to use #!/bin/sh. Of course, if you use bash-specific features in your scripts, your scripts won't be portable anyway and it doesn't really matter, I suppose.
    • by Anonymous Coward
      hash bang slash bin slash bash
    • BSD/OS ships with bash in /bin.

      And yes, I have been burned regularly by scripts which assumed that "sh" would have bash extensions.
  • Try this out! (Score:1, Informative)

    by KGB Kenny (238697)
    Why couldn't you just write a small script that chooses what shell to use at the beginning?

    Say the following:

    File 1: Shell script to determine what *nix you are running

    File 2: Bourne shell script

    File 3: bash shell script

    File 1 determines whether to use Bourne shell script of bash shel script and passes it onto decided shell.

    Just a thought... hope I could be helpful!

    -theKGB 8)
    • Re:Try this out! (Score:2, Insightful)

      by anothy (83176)
      problems here:
      first, what's the first script to be written in, that it'll run on any unix? i guess this is easier than the general case, but still not an issue to ignore.
      also, this more than duplicates the work of writing and maintaining these scripts. you've got the install scripts twice, plus the selector script.
  • It's a non-issue. (Score:5, Interesting)

    by mindstrm (20013) on Saturday November 17, 2001 @07:42PM (#2579698)
    You are looking for a solution to a problem that does not exist.

    bash is backward compatable to sh. Period.

    Yes, you can do things in bash you can't do in sh, but not vice-versa.

    If you write your scripts for stock Bourne, they will run fine under bash.
    • by // (81289)
      It's not *quite* a non-issue.

      If you want to use sh, start with #!/bin/sh rather than #!/bin/bash - the executable notes which name you invoke it with and adjusts a couple of minor details of behaviour accordingly.
      • yes.. and there are a few other, very minor differences, well documented in the bash documentation, which any devleoper could very easily account for.
    • Re:It's a non-issue. (Score:5, Informative)

      by pete-classic (75983) <hutnick@gmail.com> on Saturday November 17, 2001 @08:09PM (#2579781) Homepage Journal
      What you are saying is valid, but it misses the point.

      Even if every valid bourne script runs perfectly under bash there is still a problem.

      That problem is that an interpreter enforces valid syntax. It would be nice if everyone who wanted to write a portable (read bourne) script spent a month studying and was totally zen-ed out on the subject. But that 'aint the real world.

      I personally could benefit from a real sh on Linux, since it is the only *NIX I have, and I can't test scripts for sh compatibility without it.

      To be more specific, I wrote a bash script that was included in an OSS project. The maintainer wanted me to change the first line from "#!/bin/bash" to "#!/bin/sh" "for compatibility." I told him that I wasn't comfortable with this since the script wasn't tested on sh. He said he tested it and it worked fine. I asked him if he really tested it with sh or with "/bin/sh -> /bin/bash". Turned out it was the latter. Apparently he made the change anyway.

      A while later we got a bug report on the list to the effect "your script is not a valid sh script." Luckily the guy sent a diff, and I tested it with bash. I guess it works with sh now too, but I still don't know for sure.

      See how it isn't a non-issue, at least for me?

      -Peter
      • I personally could benefit from a real sh on Linux, since it is the only *NIX I have, and I can't test scripts for sh compatibility without it.

        Next best thing is to test with ash - I do this for exactly the reason you outlined in your post (great post btw). You still won't catch things like using $() instead of ``, of course, but most Unix vendors nowadays seem to have a POSIX /bin/sh anyway. I usually use `` anyway when I want the script to be portable, but $() is so much more readable ... <sigh>

        -another Peter

      • Re:It's a non-issue. (Score:2, Informative)

        by psaltes (9811)
        > What you are saying is valid, but it misses the point.

        Actually, what he says is not even valid. If anyone had bothered to read the link that Cliff helpfully posted, they would see that there are several things bash does not do, and several things that are 'implemented differently'. The following is taken from that page:

        Things sh has that bash does not:
        uses variable SHACCT to do shell accounting
        includes `stop' builtin (bash can use alias stop='kill -s STOP')
        `newgrp' builtin
        turns on job control if called as `jsh'
        $TIMEOUT (like bash $TMOUT)
        `^' is a synonym for `|'
        new SVR4.2 sh builtins: mldmode, priv

        Implementation differences:
        redirection to/from compound commands causes sh to create a subshell
        bash does not allow unbalanced quotes; sh silently inserts them at EOF
        bash does not mess with signal 11
        sh sets (euid, egid) to (uid, gid) if -p not supplied and uid 100
        bash splits only the results of expansions on IFS, using POSIX.2
        field splitting rules; sh splits all words on IFS
        sh does not allow MAILCHECK to be unset (?)
        sh does not allow traps on SIGALRM or SIGCHLD
        bash allows multiple option arguments when invoked (e.g. -x -v);
        sh allows only a single option argument (`sh -x -v' attempts
        to open a file named `-v', and, on SunOS 4.1.4, dumps core.
        On Solaris 2.4 and earlier versions, sh goes into an infinite
        loop.)
        sh exits a script if any builtin fails; bash exits only if one of
        the POSIX.2 `special' builtins fails
      • I had a similar problem. A friend of mine wrote a shell script (#!/bin/sh) for Mac OS X. I brought it over to my NeXT, and it didn't work, because it used zsh constructs that weren't supported in the Bourne shell. It was easy to fix, but it's a good illustration of the type of problem you're talking about.
    • by seebs (15766) on Saturday November 17, 2001 @08:35PM (#2579845) Homepage
      Embrace and extend. There is no way to write a script in bash and have bash warn you if you're using an extension, so they tend to creep into scripts. Embrace and extend is evil; the compatability mode should be *pure* sh, with no extensions.
      • Just to play devil's advocate here for a minute -- if we're only ever allowed to implement what the standard dictates, how will we ever come up with anything new?

        I mean, sure, you can sit down and write a totally new scripting language.

        And no one will use it.

        All computer systems change evolutionarily. C has evolved within itself quite a bit. C++ is a superset of C, with some caveats. Java is a language whose syntax inherits a lot from the C family, but is quite different.

        Linux is like many other previous Unixes, except ... that it's an evolution, and is different.

        It causes problems. It makes life difficult (everyone who's programmed Unix-like OSs knows that's a pain in the butt).

        But are you seriously going to argue that we should have stuck to the one official narrow definition enshrined by ATT in the early 80s, and that no new implementation should differ in the least?

        ...

        I would argue that "Embrace and extend" refers to, specifically, "Embrace and extend with non-standard, non-free additions that lock customers into our products and only our products, forever".

        Anyone is free to make ksh or ash (or whatever) have a bash bug-compatibility mode to make people's lives easier in porting scripts. Hell, the Linux kernel has bug-compatible syscalls.

        It's a pain. But it's also progress.
        • Extending your point: is there *any* system today that includes sh and only sh as its script interpreter? Is there any compelling reason (other than standards purity) not to just `rm sh; mv bash sh`?
          • Yes, actually :-)

            Bash is (arguably) a piece of junk. And it's definitely not intended as a system scripting shell.

            /bin/sh should be ksh or ash.

            zsh is almost definitely a nicer end-user shell (but is, like bash, too bloated for system use).

            ...

            (for the record, I think Solaris comes with "just" a /bin/sh, which is pure Bourne. HP-UX and AIX come with ksh).
        • Adding features is good, but keep them out of the thing that claims to be the standard version of the language. /bin/sh should be a POSIX shell, period.

          This is why ksh is called "ksh", not "sh".
        • YDGI. The point isn't that bash shouldn't implement anything new. The point is that bash should have a mode where all the new stuff is turned off.

          Look at gcc for an example of this. Gcc has extensions, and they are useful and used. No one has a problem with this. But sometimes people want to use gcc to develop truly portable programs. When they do, they use "-ansi -pedantic" (I think; IANAP) to turn off all of the gcc extensions.

          Linux would be a better citizen in the community of unix variants if its Bourne shell implementation offered a similar no-extensions option.
      • From a diary entry I posted in advogato [advogato.org] a few days ago:

        7 Nov 2001 (updated 7 Nov 2001)

        Bash bashing

        Let me state that I have nothing against bash itself. I know it's a very fine, full featured shell with many interesting improvements over other shells. Most, if not all, Linux distributions use it as the system's /bin/sh, which is also fine, but it's the fact that it leaks bash-isms when invoked as sh that is somewhat disturbing. First of all, it allows the creation of a multitude of /bin/sh scripts that are not compatible with the Bourne shell -- replace /bin/sh by ash in your system to see the extension of the damage. Now take your bash-contaminated /bin/sh scripts and try to run them in other, erm, Linux-like systems such as commercial SysV or even BSDs. You can try /bin/ksh, but it won't work in all cases, and you'll be forced to use bash. That's, IMHO, very Microsoftian in nature. It's embrace and extend.

        What I advocate here is that bash scripts must use #!/bin/bash, not #!/bin/sh. Let Bourne shell scripts use #!/bin/sh, Korn shell scripts use #!/bin/ksh, C shell scripts use #!/bin/csh and so on. Let's stick on standards. It just makes sense!

  • by dangermouse (2242) on Saturday November 17, 2001 @07:44PM (#2579708) Homepage
    Slackware uses ash because (a) it's tiny and (b) it's restrictively Bourne-compatible, which means you won't write some tool that is accidentally dependant on bash.

    Basically, Slackware uses ash for development for the exact reasons you're looking for a Bourne-compatible shell.

    Have fun.

    • The Bourne shell is written to interpret an Algol-like language. Think about that. The original source code had very ugly preprocessor tricks to make C look like Algol. Steve Bourne had Algol on the brain, it was really ugly.

      Who uses Algol today? We now have much more elegant shells like "rc", either the "rc" clone that is shipped with most Linux systems, or maybe even the original Plan 9 "rc" designed and written by Tom Duff.

      There is some room for improvement in the art here. It bothers me that the first goal is to be compatible with something that ran in 1971.

      Thanks

      Bruce

      • Re:Too much history (Score:2, Interesting)

        by Evangelion (2145)

        There is some room for improvement in the art here. It bothers me that the first goal is to be compatible with something that ran in 1971.


        That "goal" is to provide people on Linux with a shell with which they can develop portable sh scripts. One that, by being written to, allow you to write scripts that will run on all the other POSIXish sh's out there on other Unicies. Because, well, those things are nessecary in the real world.

        Why does giving system administrators and developers what they need to make thier lives easier bother you?
      • Well, the reality at the moment is that most people and systems use a Bourne-compatible shell, and /bin/sh is almost universally a Bourne-compatible shell.

        So it makes sense to develop startup scripts and basic tools for Bourne. From there, it's a small step to "it makes sense to develop under Bourne", which is the point I was addressing in my original response.

        Very few people use a strict Bourne shell on a regular basis. It's just the lowest [most-]common denominator. If something more featureful and less weird were to take its place, I'd be down with that.

        (BTW, I obviously don't speak for Slackware. It'd be really nice if Slash would stop displaying that email address. I asked it to do so, even gave it a new one to display instead...)

      • Re:Too much history (Score:2, Informative)

        by taniwha (70410)
        ok - as a one-time algol programmer, and user of Unix V6 (god I'm dating myself :-) - I think Steve had Algol68, not Algol itself on the brain.



        Circa 1971 Algol68 was a 'state of the art launguage', mind you it was one that proved to be a bit too hard to implement well. Most of the easy stuff ended up in Pascal (and some in pascal).



        C's 'struct' and 'union' keywords for example almost surely came from (or via) algol68

        • I'd accept "Algol68". I came on the Unix scene in 1981, but we still had V6 systems, and a commercial application (the Images paint system from NYIT Computer Graphics Lab "CGL Inc.") that lived on V6 until 1988 or so. I actually ported the 2.8BSD segmentation overlay loader back to V6, along with fsck, etc.

          Bruce

  • bash as /bin/sh (Score:4, Informative)

    by zdzichu (100333) <zdzichu@@@irc...pl> on Saturday November 17, 2001 @07:45PM (#2579710) Homepage Journal
    "On every distro I've ever seen /bin/sh is just a soft link to /bin/bash."
    You haven't seen Polished Linux Distribution [pld.org.pl]. PLD's /bin/sh is not bash, and all 'bashisms' are removed from distribution's scripts - it's all plain /bin/sh.

    (Plus, PLD is fully IPV6 ready :)
  • by psamuels (64397) on Saturday November 17, 2001 @07:45PM (#2579711) Homepage
    Do you think that the startup scripts for most distributions would break because, even though they say #!/bin/sh at the top, they REALLY mean #!/bin/bash?

    Many would. However, note that POSIX requires /bin/sh to be a POSIX shell, whose specs are derived mostly from the Korn Shell - so ksh is a valid POSIX shell, as is Bash, modulo a few features. Plain-vanilla Bourne shell is not.

    AIX has the same dilemma: to be POSIX-compliant they have /bin/sh -> ksh and /bin/bsh is the real Bourne. HP-UX 11 has /bin/sh distinct from ksh, but it too allows things like 'export FOO=BAR'. I don't know if a real Bourne shell exists on HP-UX.

    For a POSIX shell without the bash overhead, use ash, which is distributed with many (most?) Linux distributions. ash is the NetBSD /bin/sh, and at least on Debian the installation gives you the /bin/sh symlink option as well. Let me tell you, ash is much faster than bash in the autoconf-generated-configure "benchmark".

    Since many Debian people use ash for /bin/sh, packages regularly have bugs filed -- and fixed -- vis-a-vis #!/bin/sh vs. #!/bin/bash. I don't know how careful other distros are about this sort of thing. Note that even many Debian scripts would fail if you found a real Bourne shell for /bin/sh rather than a POSIX-compliant shell.

    • Yeah, you're right - /bin/sh should probably refer to ksh. The problem, of course, is that most distros implement ksh using pdksh, which throws some slightly interesting behavior into the mix as well. For instance, even though the UNIX 1 spec says that the last process in the pipe chain can be implemented in sub-shell, practically all implementations do not, except for pdksh.
      I wish distros would pick up the AT&T ksh implementation, since it is actively maintained, standards compliant, and since the source code is available to mere mortals now.
  • Ash (Score:3, Interesting)

    by ^chewie (65165) on Saturday November 17, 2001 @07:46PM (#2579716) Homepage

    Ever try ash [debian.org]? Here's a size comparison just to intrigue you a bit.

    (82780) /bin/ash*

    (407356) /bin/bash*
  • by Anomie-ous Cow-ard (18944) on Saturday November 17, 2001 @07:47PM (#2579719)
    Do you think that the startup scripts for most distributions would break because, even though they say #!/bin/sh at the top, they REALLY mean #!/bin/bash?

    I couldn't say for other distros, but Debian policy [debian.org] says that /bin/sh can be any POSIX-compatible shell, with the one extension that 'echo -n' must not generate a newline. If any script uses /bin/sh assuming bash features, it's considered a serious-level bug.

  • Just so you know, I built a ksh93 (the Korn shell) rpm. It's at http://dan.drydog.com/packages.php [drydog.com]

    For information on Korn shell, see http://www.kornshell.com/ [kornshell.com]

    With ksh, you can more easily interoperate with commercial UNIX systems, which now a days all come with ksh.

  • I've read the list of differences in the FAQ. It's just a big list of extensions to the Bourne shell. It doesn't list any incompatibilities (except for a couple of obscure missing features which you probably shouldn't use anyway). If you write something in standard Bourne syntax, there should be no problems with Bash.

    If you, on the other hand, test it with Bash, and then assume it will run under any other Unix... Well, you shouldn't do that with GNU software :)
  • I don't know the exact reason why... I barely know anything about shell scripting... but some shells that say /bin/sh will only work on my system if they use bash. Ash fails due to some difference in how it handles parentheses or file names or something... hopefully someone who knows shell scripting can elaborate ;)
  • "If bash is invoked with sh as its name (argv[0]) then its supposed to act like Bourne - but that just doesnt happen (for example: export FOO=bar is *not* valid Bourne shell syntax, you must say FOO=bar; export FOO)" Not quite right. the syntax export VAR=VALUE is a shorthand method. It is still perfectly alright to VAR=VALUE and then export VAR. I've not run into a comptability problem running scripts under bash, but that does not mean they exist. You can of course recompile bash to function differently ie, for statements can act more like C for statements then their bash versions. Still, tinkering with your shell nulls all warranties, in a sense anyway. Bash has a huge install base and is most likely the shell you will find on most linux systems. If you are really interested in supporting it, you will most likely have to code around its problems. ie, doing a revision check and using X function instead of Y.
  • by mj6798 (514047) on Saturday November 17, 2001 @08:01PM (#2579760)
    There have been lots of different versions of the "real Bourne shell" over the years. From a practical point of view, you should have no problem writing scripts that run in bash and in whatever shell you consider "real". Stick to the POSIX specs where possible.

    However, why are you writing "installer scripts" anyway? If you want to deliver on Linux, please use the Linux packaging system. If you deliver on Solaris, please use the Solaris packaging system. Etc.

    • If you want to deliver on Linux, please use the Linux packaging system.

      What is the Linux packaging system?

    • However, why are you writing "installer scripts" anyway? If you want to deliver on Linux, please use the Linux packaging system. If you deliver on Solaris, please use the Solaris packaging system. Etc.

      The Linux packaging system? There are several, at least three of which (rpm, deb, tgz) are in common use.

      It's a valid question, but there are a lot of packaging systems out there - the ones for AIX, HP-UX and IRIX don't resemble each other in the least. Besides, while I don't mind installing packages on AIX or IRIX, the HP-UX 'depot' format and supporting tools are so clumsy that I'd rather run a vendor install script, and worry about uninstalling "manually", any day of the week. (In practice, vendors like Dassault, PTC and MSC never use the native install format - they always supply a script. And that script always seems to assume POSIX shell features. It is also always poorly-written, but that's a different rant.)

    • The Linux Packaging System?

      Sorry, but do you mean deb files, or rpm's, or perhaps a gzipped tarball with a makefile inside?

      When there's no real set standard, it's fine to write an install script. Plenty of programs do it.
    • Well, under Linux anyways there are at least 3 packagers that are used for Linux distributions.

      In any case, programs like my EPM (see http://www.easysw.com/epm/ [easysw.com] for more info) are designed to create installation scripts, or RPM packages, etc. Definitely worth a look if you want to ship binaries for multiple platforms or even just multiple Linux distributions...

  • by MarkusQ (450076) on Saturday November 17, 2001 @08:17PM (#2579804) Journal
    I think that there is some confusion here. The_code_poet clearly asked about compatibility going from sh to bash (i.e., he wants to write standard sh scripts and have them work on linux, and therefore bash). But the incompatibilities everyone is discussing (e.g. initialized export syntax) are all going the other way; things that you can write under bash that won't work under sh. So what?

    The things that matter are first, the things sh has that bash does not (from the FAQ):

    * uses variable SHACCT to do shell accounting
    * includes `stop' builtin (bash can use alias stop='kill -s STOP')
    * `newgrp' builtin
    * turns on job control if called as `jsh'
    * $TIMEOUT (like bash $TMOUT)
    * `^' is a synonym for `|' * new SVR4.2 sh builtins: mldmode, priv

    ...and the implementation differences:

    * redirection to/from compound commands causes sh to create a subshell
    * bash does not allow unbalanced quotes; sh silently inserts them at EOF
    * bash does not mess with signal 11
    * sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100
    * bash splits only the results of expansions on IFS, using POSIX.2 field splitting rules; sh splits all words on IFS
    * sh does not allow MAILCHECK to be unset (?)
    * sh does not allow traps on SIGALRM or SIGCHLD
    * bash allows multiple option arguments when invoked (e.g. -x -v); sh allows only a single option argument (`sh -x -v' attempts to open a file named `-v', and, on SunOS 4.1.4, dumps core. On Solaris 2.4 and earlier versions, sh goes into an infinite loop.)
    * sh exits a script if any builtin fails; bash exits only if one of the POSIX.2 `special' builtins fails

    None of these seem to me to be show-stoppers if you are writing the script from scratch (or even porting a reasonably written one)--I mean really, are you counting on it to dump core if you use multiple option arguments? Is there some reason you can't ballane your quotes? So my question to the_code_poet is, what exactly are you trying to do in sh that won't work in bash?

    --MarkusQ

  • Obviously what the author wants is a shell which implements just the POSIX standard and nothing else. Or maybe expanding just a little bit, wants a shell which JUST implements the Bourne syntax which is available in all Bourne-compatible shells.

    I can understand the reason for this when writing an install script - specifically it is desirable to write to the lowest common denominator and thus make it compatible with everything.

    However, I can't think of a single shell which actually implements just POSIX, or Bourne syntax for that matter. There are dozens of shells out there which all will chew on a real POSIX or Bourne script and spit out something which is pretty close to what the script author intended. However it seems that all of the shell authors have done stuff a little differently than each other so if you've only written and tested on one shell, you might have problems running on any one (or all) of the other shell(s).

    The best thing to do is to pick something small which is as close to just POSIX implementation as you can get (ash perhaps?) and write/develop in that shell and then thouroughly test it on things like bash, ksh and other POSIX shells.

    I always like to through out the fact that most systems now have perl available on them and in some cases it is probably just as appropriate if not more so to script install stuff in perl.

  • I've run into this problem in the past as well. My solution was to abandon Bourne shell as a scripting shell and use ksh instead. To be 100% portable, you should use Bourne, but most of your major *NIXes have support for ksh (including linux, Solaris and AIX..not sure about HP-UX) and it has a lot of nice scripting gizmos like associative arrays, printf command, co-processes, pattern matching, etc. Of course, maybe you don't need all of that stuff.

    As an aside, there has been a lot of extensive research on making portable shell scripts. Bruce Blinn's book Portable Shell Programming: An Extensive Collection of Bourne Shell Examples [amazon.com] is a good resource that might help as well as GNU Autotools documentation [huji.ac.il], which is the definitive guide on this sort of thing. Another useful jumping off point that has some good materials and a lot of useful links is Shell Script Porting Guidelines [raycosoft.com]
  • Linux Standard Base (Score:5, Informative)

    by kingdon (220100) on Saturday November 17, 2001 @10:38PM (#2580072) Homepage

    Others have addressed the various issues about what is a "real" Bourne shell and bash extensions and all that. Anyway, the Linux Standard Base has a section [linuxbase.org] on shells. In a nutshell, bash 2.x was the most POSIX-compliant of the shells that the LSB tested (and no, I don't know exactly what versions or which shells or the like), with pdksh getting an honorable mention. And there were two ways in which bash was not POSIX-compliant and concerning which the LSB therefore diverges from POSIX (whether $0 is the full pathname or just the basename, and what happens if you try to use "." to run a script without the read bit set). I don't know whether a future version of POSIX is planning to change the specification, or whether this is likely to remain a divergence for the foreseeable future or what. In any event, these two issues shouldn't be hard to deal with in writing scripts.

  • Example bash bug (Score:3, Interesting)

    by kevin@ank.com (87560) on Saturday November 17, 2001 @10:49PM (#2580090) Homepage
    To be honest, I have yet to run into much trouble with a script starting with #!/bin/sh with /bin/bash, and I've been using the latter for years. If any of you have had problems related to this, please tell us what the problem was and how you solved it.

    The following works in UNIX sh, but not in bash:

    /sbin/ls -l | while read bits links user group size junk ; do
    echo $user $group
    done

    To work around the bug you can either put the output of ls into a file and redirect input to read from the file, or you can use an immediate mode file (EOF) in the script, but pipes are broken with respect to read.

    • Re:Example bash bug (Score:2, Interesting)

      by wayne (1579)
      You don't say what the results from using bash are, but your code worked just as I would expect on my Debian system using bash. That is, it prints out the user and group of each file in the current directory. Well, I had to change /sbin/ls to ls (or /bin/ls), but that doesn't seem to be a problem with bash...
    • Works just dandy with bash on my box. Cygwin bash at that.
  • Actually, is writing korn or bourne shells the way to go?
    We're year 2001. ZSH, Bash and Tcsh are there for years, and they work on all platforms out there, including Windows. They provide a lot of enhancements over Ksh and sh (kick-ass completion, readline, floating point arithmetic, a lot of handy shortcuts and builtins, etc) .
    So, the way to go is probably to use nowaday's tools, not 20-years old ones.

    • "They provide a lot of enhancements over ksh and sh (kick-ass completion,"

      So does ksh.

      "readline,"

      If you mean inline editing, more generally, so does ksh, using both Emacs and vi keybindings if you wish.

      "floating point arithmetic,"

      Yep, so does ksh.

      "a lot of handy shortcuts and builtins, etc)."

      Well, you know what this line would be, right?

      A lot of Linux distributions are using "pdksh," which is based on an earlier standard. Ksh is actually a pretty advanced scripting language (with indexed and associative arrays, compound variables, 'printf' formatting and an execution-tracing debugger), and theoretically it's 100% backward-compatible with sh.

      Personally I've taken to zsh myself, but don't 'dis' ksh. :) It's pretty sophisticated. It's unfortunate that 'ksh93' hasn't made its way into wide use, or at least wide inclusion in distributions, yet; linking '/bin/sh' to the 1993 ksh release might be a little more 'true sh compatible' than bash, which is really what this topic was about.

  • The problem is that Linux programmers don't stop to think about whether the shell they use e.g. during installation or with wrappers, is actually present on the system.

    Being a solaris admin I regularly have to edit shell scripts to put the right path for bash in (/opt/local/bin/bash).

    Software programmers should make their code more portable. In other words, fix configure to look for bash in the path and use that at the top of installation/wrapper scripts. In normal circumstances making the fixes isn't that much work, but you can see that it becomes much more of a problem when compiling something as humungous as Gnome because you can't automate the compiles/installs.
  • apt-get -y install ash ; ln -sf ash /bin/sh

    This actually works pretty well, and it's great for finding broken sh scripts.

  • The term ``Bourne Shell'' is historic; it refers to the original program written by Stephen Bourne and some more or less direct derivatives.

    The modern thing is simply the POSIX shell command language; If you write in the POSIX language, avoiding the quirks and extensions in the proprietary implementation you are using, your script should be highly portable to GNU bash and vice versa.

    Similarly, if you want to write a new shell, your best bet is to use the standard as the guide rather than to clone the behavior of the legacy Bourne shell.

    If you don't know what is standard and what is not, try the draft Single Unix Specification [unix-systems.org] online.

    Search for ``shell command language''.

The end of labor is to gain leisure.

Working...