tneff@bfmny0.UUCP (Tom Neff) (07/08/89)
I use Korn shell and am happy with it, but I want certain shell scripts to be intepreted by the Bourne shell instead. There is already a mechanism by which CSH(1) figures out to spawn /bin/sh on a script rather than interpreting itself, namely putting a colon ':' as the first line. % cat > xxx : ps ^D % chmod a+x xxx % xxx PID TTY TIME COMMAND 27632 console 0:00 csh 27640 console 0:00 sh 27641 console 0:00 ps What I want to know is, is there any way to do this under K-shell? The colon certainly doesn't work, and neither does #! /bin/ksh or anything else I've tried. Sure would be nice. -- "My God, Thiokol, when do you \\ Tom Neff want me to launch -- next April?" \\ uunet!bfmny0!tneff
cks@ziebmef.uucp (Chris Siebenmann) (07/12/89)
In article <14445@bfmny0.UUCP> bfmny0!tneff@uunet.UU.NET (Tom Neff) writes: | I use Korn shell and am happy with it, but I want certain shell | scripts to be intepreted by the Bourne shell instead. On a BSD Unix, one could put "#! /bin/sh" at the start of your script and it would work. Unfortunately, System V doesn't have this (and worse yet, your vendor has gratuitusly hacked csh so many scripts will break under it), so the best substitute (swiped from Perl v2's Configure script) is: (alias) >/dev/null 2>&1 && (exec /bin/sh $0 ${1+"$@"}) -- "Oh BLESS you, sir! The ANGEL OF DEATH was after me just as SURE as you're standing there, yes he WAS!" Chris Siebenmann uunet!{utgpu!moore,attcan!telly}!ziebmef!cks cks@ziebmef.UUCP or .....!utgpu!{,ontmoh!,ncrcan!brambo!}cks
trent@cs.dal.ca (Trent MacDougall) (07/13/89)
From article <14445@bfmny0.UUCP>, by tneff@bfmny0.UUCP (Tom Neff): > I use Korn shell and am happy with it, but I want certain shell > scripts to be intepreted by the Bourne shell instead. There is > already a mechanism by which CSH(1) figures out to spawn /bin/sh > on a script rather than interpreting itself, namely putting a > colon ':' as the first line. > > What I want to know is, is there any way to do this under K-shell? > I was just going to send Todd Day this note. His postings about setting up C News helped me and I wanted to return the favor. I put the following at the beginning of the file /usr/local/lib/news/bin/config. if [ "$RANDOM" != "$RANDOM" ] then /bin/sh -c "$0 $*"; exit $? fi This will force all shell scripts to be run under sh instead of ksh. -- //_//_//_//_// Trent MacDougall @ Dalhousie University, CS Dept. \\_\\_\\_\\_\\ UUCP {uunet watmath}!dalcs!trent // // // // // INTERNET trent@cs.dal.ca
tneff@bfmny0.UUCP (Tom Neff) (07/13/89)
My thanks to all who have responded via mail or news posting to my question about forcing the Korn shell (KSH) to run a script using the Bourne shell (SH) instead of itself. There have been no completely satisfactory answers, but I will summarize the State Of What Is Known. * There are a few minor incompatibilities between the way SH and KSH behave in a correctly written script, but the biggest reason why you would want SH to run a script instead of KSH (if it's simple and dumbed down to SH) is that KSH takes a lot longer to fork itself. Thus tricks that let KSH, once forked, realize it should hand the reins over to SH (such as [ "$RANDOM" = "$RANDOM" ]) are not enough; you not only have to spend the time forking KSH but also the time to reinvoke SH. * There is an exact analogue to what I want for the C-Shell (CSH): if you put a colon ":" as the first line of a script, CSH will detect it and automatically spawn SH instead of itself to execute the script. (This is the way AT&T documents it; some users claim that putting *anything* other than "#" at the start of the first line does it, or that a blank first line does it, but I recommend sticking with the AT&T convention to avoid blowing up on someone's weird CSH variant.) You can see this done at the start of most of the AT&T supplied system shell scripts like installpkg and shutdown and even basename. But no, it does not convince KSH. To prove this, create the script : ps -f * If you must use one of the "tricks" like Todd Day's $RANDOM thing, for the sake of correct (though not faster) script execution, you should follow up with "exec" rather than sub-spawning SH underneath the KSH process. test "$RANDOM" = "$RANDOM" && exec /bin/sh -c $0 $* or to force KSH: test "$RANDOM" = "$RANDOM" || exec /bin/ksh -c $0 $* * Although you can't escape KSH's long fork time (apparently), you can definitely escape the potentially lengthy process of glomming your ENV environment script for every subshell, by using the ENV trick described in the KSH documentation: export Envfile=$HOME/.env export ENV='${Envfile[(_$-=1)+(_=0)-(_$-!=_${-%%*i*})]}' This cryptic mass will run your environment script (presumably including your favorite functions and aliases etc., and in this example named ".env" in your home directory) if and only if you spawn an interactive shell, such as a naked "!" from rn(1) or vi(1). If you spawn a command directed subshell, a la "ksh -c echo hi", the environment script won't run and your subprocess will get going a whole lot faster. If anyone has an answer to the original question, operators are still standing by. :-) If no one does, and if Dave Korn (or the fellow who famously sits right next to him) is listening, an auto-SH convention in scripts would be a Nice Thing To Have next version of KSH. -- "My God, Thiokol, when do you \\ Tom Neff want me to launch -- next April?" \\ uunet!bfmny0!tneff
ford@cbmvax.UUCP (Michael "Ford" Ditto) (07/13/89)
In article <1989Jul12.191342.1048@cs.dal.ca> trent@cs.dal.ca (Trent MacDougall) writes: > if [ "$RANDOM" != "$RANDOM" ] > then > /bin/sh -c "$0 $*"; exit $? > fi > >This will force all shell scripts to be run under sh instead of ksh. Umm ... not quite -- sometimes ksh would still be used, at RANDOM, you might say (anytime $RANDOM happens to return the same value both times). The example also trashes the argument list. -- -=] Ford [=- "The number of Unix installations (In Real Life: Mike Ditto) has grown to 10, with more expected." ford@kenobi.commodore.com - The Unix Programmer's Manual, ...!ucsd!crash!kenobi!ford 2nd Edition, June, 1972. ditto@cbmvax.commodore.com
tbertels@cipc1.Dayton.NCR.COM (Tom Bertelson) (07/15/89)
In article <1989Jul11.225839.14835@ziebmef.uucp> cks@ziebmef.uucp (Chris Siebenmann) writes: > On a BSD Unix, one could put "#! /bin/sh" at the start of your script >and it would work. Unfortunately, System V doesn't have this (and >worse yet, your vendor has gratuitusly hacked csh so many scripts will >break under it), so the best substitute (swiped from Perl v2's >Configure script) is: > > (alias) >/dev/null 2>&1 && (exec /bin/sh $0 ${1+"$@"}) A minor nit. If you have an interactive program called "alias" on your system (as I discovered here) you could be in for a surprise. Try instead (PATH= alias) >/dev/null 2>&1 && (exec /bin/sh $0 ${1+"$@"}) Some day I'll send this off to Larry Wall ... -- Tom Bertelson DISCLAIMER: My opinions are my own and Tom.Bertelson@Dayton.NCR.COM in no way reflect those of my employer. ...!uunet!ncrlnk!cipc1!tbertels
ned@pebbles.cad.mcc.com (CME Ned Nowotny) (07/19/89)
In article <14463@bfmny0.UUCP> tneff@bfmny0.UUCP (Tom Neff) writes: >My thanks to all who have responded via mail or news posting to my >question about forcing the Korn shell (KSH) to run a script using the >Bourne shell (SH) instead of itself. There have been no completely >satisfactory answers, but I will summarize the State Of What Is Known. > ... Lines Deleted ... > > * There is an exact analogue to what I want for the C-Shell (CSH): > if you put a colon ":" as the first line of a script, CSH will > detect it and automatically spawn SH instead of itself to execute > the script. (This is the way AT&T documents it; some users claim > that putting *anything* other than "#" at the start of the first > line does it, or that a blank first line does it, but I recommend > sticking with the AT&T convention to avoid blowing up on someone's > weird CSH variant.) You can see this done at the start of most of > the AT&T supplied system shell scripts like installpkg and shutdown > and even basename. But no, it does not convince KSH. To prove this, > create the script > > : > ps -f > There is some missing history here. In the old days (around Version 6 or 7 and before), the Bourne shell did not have a comment character, but it did have the null command, ":". Now, the null command was useful in several ways (e.g. ":" is a trivial true command - this was important when "true" was not a built-in and required a new process to be forked). In fact, one of the most useful things you could do with ":" was to comment your shell script since ":" does nothing with the arguments (a.k.a. comment string) that you may provide it. While modern Bourne shells include both the "#" comment character and a built-in "true", they also still include the null command, ":". As a consequence, the Korn shell also includes the null command and its original semantics. So no, it can not be used to distinguish a Bourne shell script from a Korn shell script. On the other hand, the C shell did use the "#" as a comment character in the early days. As a result, shell scripts that started with a "#" were almost certainly C shell scripts beginning with a comment (as all good code should). Therefore, the C shell could be preferentially forked just by determining whether the script began with a "#". While BSD went on to provide the more general script mechanism using "#!", AT&T never really did much better than use the old comment character trick. This even after the Bourne shell gained the "#" comment character and despite the inclusion of the C shell by UNIX vendors. (Of course, AT&T did not include C shell as part of its stock UNIX distribution for many years, so the conflict was a non-problem from their point of view.) So while I can't provide a solution to your problem given that your system does not support the "#!" mechanism, I hope this history may at least explain why things are the way they are (mostly, AT&T suffered from NIH - and yes, BSD suffered from "featuritis"). Errors in the above will no doubt be quickly corrected. Ned Nowotny, MCC CAD Program, Box 200195, Austin, TX 78720 Ph: (512) 338-3715 ARPA: ned@mcc.com UUCP: ...!cs.utexas.edu!milano!cadillac!ned ------------------------------------------------------------------------------- "We have ways to make you scream." - Intel advertisement in the June 1989 DDJ.
friedl@vsi.COM (Stephen J. Friedl) (07/19/89)
In article <1792@cadillac.CAD.MCC.COM>, ned@pebbles.cad.mcc.com (CME Ned Nowotny) writes: > In fact, one of the most useful things you could do > with ":" was to comment your shell script since ":" does nothing > with the arguments (a.k.a. comment string) that you may provide > it. While this is true, it can be misleading. In particular, the line cat file file2 > file3 isn't commented out by prefixing it with a colon. Cat doesn't run, but redirection *will* take place and file3 will be truncated. Steve -- Stephen J. Friedl / V-Systems, Inc. / Santa Ana, CA / +1 714 545 6442 3B2-kind-of-guy / {attmail uunet}!vsi!{bang!}friedl / friedl@vsi.com "Why can't I do pointer multiplication in C?" - Blair Houghton
ned@pebbles.cad.mcc.com (CME Ned Nowotny) (07/19/89)
In article <1152@vsi.COM> friedl@vsi.COM (Stephen J. Friedl) writes: >In article <1792@cadillac.CAD.MCC.COM>, ned@pebbles.cad.mcc.com (CME Ned Nowotny) writes: =>> In fact, one of the most useful things you could do =>> with ":" was to comment your shell script since ":" does nothing =>> with the arguments (a.k.a. comment string) that you may provide =>> it. => =>While this is true, it can be misleading. In particular, the line => => cat file file2 > file3 => =>isn't commented out by prefixing it with a colon. Cat doesn't run, =>but redirection *will* take place and file3 will be truncated. True. This is probably one of the reasons an actual comment character (#) was eventually added to the Bourne shell. Ned Nowotny, MCC CAD Program, Box 200195, Austin, TX 78720 Ph: (512) 338-3715 ARPA: ned@mcc.com UUCP: ...!cs.utexas.edu!milano!cadillac!ned ------------------------------------------------------------------------------- "We have ways to make you scream." - Intel advertisement in the June 1989 DDJ.
bob@wyse.wyse.com (07/20/89)
In Article 14223 of comp.unix.questions ned@mcc.com (Ned Nowotny) writes: < In article <14463@bfmny0.UUCP> tneff@bfmny0.UUCP (Tom Neff) writes: < >My thanks to all who have responded via mail or news posting to my < >question about forcing the Korn shell (KSH) to run a script using the < >Bourne shell (SH) instead of itself. There have been no completely < >satisfactory answers, but I will summarize the State Of What Is Known. < > < ... Lines Deleted ... < There is some missing history here. < < In the old days (around Version 6 or 7 and before), the Bourne shell < did not have a comment character, but it did have the null command, ":". < Now, the null command was useful in several ways ... ----lines also deleted---- My apologies as I did not see the original summary that Tom Neff put out, which may have already included the solution I am sending for getting ksh to exec sh. Also, this is my first posting, so if I have neglected some portion of netiquette, please let me know via e-mail :-). I have also supplied some additional stuff about uses of the colon command. As noted, using the colon command for comments is a problem because of the possible side effects. I came across the recommendation, in _Introducing the UNIX System_ by McGilton and Morgan, that it is best to place single quotes around the arguments to prevent these side effects. The colon command is also useful for evaluation of variables, as in the following: : ${CWDIR=`pwd`} which will set CWDIR to the current directory if CWDIR is not already set. If the colon command were not used the shell would then substitute this name and attempt to execute it as a commend. With respect to the original question of Tom Neff's, perhaps the following would help. It depends on the fact that both _sh_ and _ksh_ will execute the similar code, while _ksh_ adds some "extras", such as RANDOM, which _sh_ will treat differently. In _ksh_ each reference to RANDOM will cause the value of RANDOM to change. if [ "$RANDOM" -eq "$RANDOM" ] then # what you want sh to do else # exec sh on this script exec /bin/sh `whence $0` "$@" fi The _whence_ builtin generates the full pathname of the current file (assuming it is in the path) and _sh_ is used to run it. The original arguments must also be supplied to this new invocation. Using the quoted $@ above (if I understand it correctly), will guarantee that the form of the arguments on the original command line will be passed to the new script invocation in exactly the same form. I picked up the general idea from some _ksh_ examples I saw once, in _The Wizards Grabbag_ in UNIXWorld, but I am afraid I do not remember the author, nor do I have the original at hand. I have used the method and found that it works as advertised. (The original was used to guarantee that _ksh_ was run on the script, which contained _ksh_ specific code.) Hope this proves useful :-) Bob McGowan Wyse Technology, San Jose, CA ..!uunet!wyse!bob bob@wyse.com
guy@auspex.auspex.com (Guy Harris) (07/21/89)
>While this is true, it can be misleading. In particular, the line > > cat file file2 > file3 > >isn't commented out by prefixing it with a colon. Cat doesn't run, >but redirection *will* take place and file3 will be truncated. Furthermore, it means that the arguments to the ":" command are parsed, so the shell won't do what you want if you try something like : : This isn't a comment : (unless you want something rather perverse).
peter@ficc.uu.net (Peter da Silva) (07/23/89)
In article <2264@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) writes: > : > : This isn't a comment > : Perhaps it's time for the Obfuscated Shell Script contest? -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: peter@ficc.uu.net, +1 713 274 5180. | "...helping make the world Personal: peter@sugar.hackercorp.com. `-_-' | a quote-free zone..." Quote: Have you hugged your wolf today? 'U` | -- hjm@cernvax.cern.ch
kdb@chinet.chi.il.us (Karl Botts) (07/25/89)
In article <1792@cadillac.CAD.MCC.COM> ned%cad@MCC.COM (CME Ned Nowotny) writes: >In article <14463@bfmny0.UUCP> tneff@bfmny0.UUCP (Tom Neff) writes: >>My thanks to all who have responded via mail or news posting to my >>question about forcing the Korn shell (KSH) to run a script using the >>Bourne shell (SH) instead of itself. There have been no completely >>satisfactory answers, but I will summarize the State Of What Is Known. Well, let me take a shot: put the following line as the first of any script you want to run only under ksh, not sh: 2>/dev/null PPID=0 && { echo "$0: korn shell script" 1>&2; exit 1; } It's awful to look at, but it works. It's worse to type, and I haven't figured out any way to put it in a variable or alias or function or anything. The rational is this: using any of the built-in commands which are in ksh but not sh to detect the difference can never be bulletproof, because a binary (or whatever) can always be created with the same name as the ksh built-in, which will do something (who knows what) under sh. In fact, it is not a particularly remote possibility that this could happen, because writing binaries to emulate ksh built-ins is a perfectly reasonable thing to do. In fact, there is nothing that ksh can do that sh can't which can be a bulletproof test, because ksh is supposed to be a superset of sh, and even though it isn't it is legitimate for future versions to be closer to being a superset--therefore any failures of super-setness used to make a test are liable to go away. What is needed is something which sh can do that ksh can't. So far as I can tell by empiric methods there is only one such thing--assign to the PPID environment variable. (ksh can assign to RANDOM, PWD and all the others I tested.) I think it is reasonable to assume that as long as ksh implements the PPID envar, it cannot afford to permit it to be changed (since it cannot change its parent.) In fact, "typeset -r" reveals that PPID is the only built-in envar with the R/O attribute. I will be delighted if someone can improve on this miserable kludge.
ap@cbnews.ATT.COM (Alexis Porras) (07/26/89)
In article <9065@chinet.chi.il.us> kdb@chinet.chi.il.us (Karl Botts) writes: | |Well, let me take a shot: put the following line as the first of any script |you want to run only under ksh, not sh: | |2>/dev/null PPID=0 && { echo "$0: korn shell script" 1>&2; exit 1; } | ... more stuff ... |In fact, there is nothing that ksh can do that sh can't which can be |a bulletproof test, because ksh is supposed to be a superset of sh, and ... more stuff ... | |What is needed is something which sh can do that ksh can't. So far as I ... more stuff ... |I will be delighted if someone can improve on this miserable kludge. I wasn't going to do it but...put this at the top of your ksh script: echo ^false >/dev/null || exec ksh $0 "$@" (or replace "ksh" by a full path name is ksh is not in the standard PATH) Well, that's my contribution to humanity for the week!