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?
- Download FreeBSD source.
- cd
/usr/src/bin/sh; make; make install
AFAIK the BSD Bourne shell is more or less the same as the real Bourne shell."The problem with the French is that they don't have a word for 'entrepeneur'." -George W. Bush
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.
You had me at "dicks fuck assholes".
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.
hash bang slash bin slash bash
Basically, Slackware uses ash for development for the exact reasons you're looking for a Bourne-compatible shell.
Have fun.
"On every distro I've ever seen /bin/sh is just a soft link to /bin/bash." /bin/sh is not bash, and all 'bashisms' are removed from distribution's scripts - it's all plain /bin/sh.
:)
You haven't seen Polished Linux Distribution. PLD's
(Plus, PLD is fully IPV6 ready
:wq
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.
"How can you claim that you are anti-crack, while still writing a window manager?" — Metacity README
The guy writes installer scripts for a living. Every other unix has a Bourne shell implementation except Linux, and Linux's /bin/bash has incompatibilities. Telling the guy to fuck off and use something else has got to be the most ignorant thing I've ever heard. I'm sure he can tell his boss the same thing, right? "Fuck this, I'm gonna use ksh so it works on... AIX only!"
Ask Slashdot becomes less helpful by the nanosecond.
- A.P.
"Remember when the U.S. had a drug problem, and then we declared a War On Drugs, and now you can't buy drugs anymore?"
Ever try ash? Here's a size comparison just to intrigue you a bit.
assert(expired(knowledge));
On the other hand, sometimes you just don't care, and you can make full use of bash or ksh or whatever.
I couldn't say for other distros, but Debian policy 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.
--
perl -e'$_=shift;die eval' '"$^X $0\047\$_=shift;die eval\047 \047$_\047"' at -e line 1.
How is that helpful? It suggests "download[ing] the real thing and use[ing] that" with no link or even indication of where to get the real thing.
I was excited when I saw this story, and again when I saw your post, because I had the same question in the past and was never able to find a satisfactory answer.
Still haven't.
-Peter
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.
i speak for myself and those who like what i say.
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 ;)
-- Is "Sig" copyrighted by www.sig.com?
"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.
"You should always go to other people's funerals; otherwise, they won't come to yours." -- Yogi Berra
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.
Last I checked, it wasn't just the size, at all, but the whole POSIX-compliance/bourne-compat thing, anyway.
Besides, given my experiences with "bourne" on AIX/Slowlaris/HP/whatever, I'd be quite happy for the whole concept to die a horrible death, standardise on simple bash and have done.
~Tim
--
Rushing on down to the circle of the turn
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
* 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
I even submitted a story about it, but it was rejected:
This sig under construction. Please check back later.
Ok guess its never going to get modded up because it has FreeBSD in it...
s ta ble/src/bin/sh/
Here is the source to what is very close to "the real thing"
ftp://ftp.freebsd.org/pub/FreeBSD/branches/4.0-
So the answer is still, "Use the real bourne sh" and here is how you do it. Download, compile (on linux) and install to some place that won't effect linux. Have your install script call the newly made "real" shell.
Wasn't hard eh?
VANBO
I apologize if my tone comes off confrontatively :-).
/bin/sh but use bash-specific features, I agree.
I'm reacting negatively to the idiotic suggestion that people need to waste time "writing a real Bourne shell for Linux".
If you don't like bash, there are several other shells which attempt to be POSIX. Some of them are quite strict (ash). Some are optimized for scripting (ksh).
If you want to argue that bash sucks and should be replaced as the default system scripting shell, I totally agree. If you want to say that it sucks when scripts request
But for goodness sake, give some respect to the work that's been done.
...
I did see one good post noting the bash specifics that are missing, as a POSIX shell. They really are quite minor...
Simple bash -- A phrase I'd never expect to hear!
On my system:
131072 sh
688128 bash
Shut up, be happy. The conveniences you demanded are now mandatory. -- Jello Biafra
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.
1. There is no such thing as Solaris 2.8, and 2.7 only exists in some places. I assume you meant 7 and 8.
Bah, "Solaris" is the marketing name. It's SunOS 5.8. Do a 'uname -a' if you don't belive me. Besides, it fits perfectly with SunOS history... versions prior to 5.0 were BSD based, version 5.0 and newer are heavily SysV based. The whole "Solaris" name just confused everyone.
There is no such thing as Solaris 2.8, and 2.7 only exists in some places. I assume you meant 7 and 8
/bin is actually a symlink to /usr/bin, so technically it doesn't put it under /bin
You're just going to have to imagine me dressed up as Moon Unit Zappa circa 1985 as I intone from on high here:
Whatever.
Sun's breaking of a perfectly functional numbering convention for the sake of their marketeers is, well, their own lookout. Every other reader knew exactly what I was talking about, and only you were dumb and/or desperate enough to think that you could score some sort of lame debating point by pointing it out.
bash was only introduce into Solaris as of Solaris 8
Hm, I'm pretty sure I recall it showing up in one of the MU packs for 7, but I could be wrong on that count -- I was mercifully spared the experience of 7 for the most part.
From Moon Zappa straight to William Shatner: GET. A. LIFE.
News for Nerds. Stuff that Matters? Like hell.
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 is a good resource that might help as well as GNU Autotools documentation, 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
The Linux packaging system for each of the distribution(s) you are targetting. That means packaging each for Debian, RedHat, and possibly others.
Wow, do you mean with ash I could use a Pentium III 780 instead of 866? Let's face it, given Moore's law, any speed improvement less than n vs. n^2 is more or less irrelevant.
As for memory usage, bash is about 0.5 megabytes, any memory chip that small is obsolete, and very expensive. Better get 64 megs or more, compared to which both sh and bash are about zero size.
In the dependencies issue, I admit you are right. But so many other packages need those same libraries that it's very likely you'll need them anyhow.
All in all, I think this "sh or bash" thing will be an issue only in a very few restricted cases, mostly embedded systems.
This reads like a troll, but it could be sincere, so I'll treat it seriously. How do you open more than two output file or more than one input file concurrently? csh has no primitives for opening and closing files beyond redirecting a single command or pipeline. Even for something as simple as redirecting stdout to one file and stderr to another, you have to jump through hoops.
I won't read back to you the famous Considered Harmful file, but the above point is probably the main reason I would never program with csh scripts. Sure, csh has some programming features Bourne shell lacks, but ksh/bash/POSIX have those same features. Opening and closing arbitrary files is something I do in my scripts all the time.
"How can you claim that you are anti-crack, while still writing a window manager?" — Metacity README
Comment removed based on user account deletion
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 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.
The following works in UNIX sh, but not in bash:
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.
LibBT: BitTorrent for C - small - fast - clean (Now Versio
csh isn't portable
/bin/sh. It is portable. I bet that code would work on bash too.
I had to port a 1500 line csh script from Ultrix to SunOS, Solaris, Dec OSF, HP-UX, and SGI Irix.
After getting it to work on Ultrix and SunOS, I tried to get it going on Solaris. csh wasn't even portable from SunOS to Solaris!
The solution was to use
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
Bruce Perens.
FWIW, I'm currently a tcsh user, although I have been looking very hard at zsh the past week or so and will probably switch very soon now. zsh solves a lot of the problems I've been having with tcsh...
I was a tcsh user until a few weeks ago. I switched over to zsh. It takes a bit of getting used to it, but it is very nice. If tcsh had functions and stdout and stderr separation (redirecting stdout to one file and stderr to another), I probably would have continued to use it.
csh (and tcsh) do not use a C-like syntax. I'm not sure what you call it, but it sure isn't C.
AFAIK bash is GNU so vendors may have license problems including it. I think this is why Apple is not including bash in Mac OS X.
Granted, not really Linux-related answer, however it does answer the question. Also, note last para of the question -- this is not about interactivityportability.
--AP
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.
{{.sig}}
Perhaps, if you use apt and only apt, then it will work. In my case, I have tried "upgrading" a system where some of the packages where more up-to-date than the apt package in the FTP server (I had already compiled newer versions from source). Disaster.
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.
I have done 20 or so solaris installs, and I can tell you my least favorite part is bootstraping the machine to the point that my config scripts can take over...
Er, not heard of Jumpstart, have you?
News for Nerds. Stuff that Matters? Like hell.
Have you ever heard of shared-copy-on-write executables?
Have you heard of U.S. Patent 4,742,450 on the shared-copy-on-write memory segments that loading such executables requires?
Will I retire or break 10K?
All in all, I think this "sh or bash" thing will be an issue only in a very few restricted cases, mostly embedded systems.
By dismissing embedded systems as a "few restricted cases," you misunderestimate their ubiquity and importance. Go to Worst Buy or Shircuit Shitty and look at the PC section vs. the sections that have TiVo, WebTV, GameCube, etc. Do you see more PCs on the shelf, or more embedded devices on the shelf? For instance, TiVo runs a Linux kernel, and Dreamcast and PS2 also have Linux available. (Sony will soon bring PS2 Linux Kit to the U.S.) Now would you rather run bash (Bloated A$$ SHell), or would you rather run something smaller and be able to add more features on a given set of fixed hardware such as a game console or a poor student's PC?
Will I retire or break 10K?
This actually works pretty well, and it's great for finding broken sh scripts.
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 online.
Search for ``shell command language''.
The provided example for pointing out the problems with bash was just a really bad pick.
You are not required to use teh shorthand initialization of a variable at export. It is a shotcut and that is all. It is not necessary to use that shortcut. So, while yes it does not behave exclusively like bourne, it is a frivilous point.
I would have liked to have seen some better examples.
"You should always go to other people's funerals; otherwise, they won't come to yours." -- Yogi Berra