Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Full path with ksh emulation




----- Original Message ----- From: "Peter Stephenson" <pws@xxxxxxx>
To: <zsh-users@xxxxxxxxxx>
Sent: Thursday, January 05, 2006 7:44 AM
Subject: Re: Full path with ksh emulation


"Tony Hasler" <tony@xxxxxxxxxxxxxxxxxxxx> wrote:
Accordingly, they have hit upon the idea of using zsh to emulate ksh. That certainly solves the original problem, but introduces a new one. In ksh the
'whence' command always gives you the absolute path of its argument.  So
'whence $0' always gives a full path even if the command was executed by
typing './myscript'. I can find no straightforward way to do this in zsh.

Why arent they just using the real ksh93? It's readily available precompiled for linux. You didn't say what distribution, but for example, on SuSE it's right there in yast easy as pie.
Drop it in there and you're done without messing with the scripts at all.

I did just get done saying how ksh93 is not a 100% drop-in for ksh88 that ships with Solaris and HP-UX, but it's certainly closer than pdksh or zsh.

I have run into other subtle things with zsh's ksh that break things. Example: In real ksh, TTY is set by the shell, but you may overwrite it, and if you export it, the value holds in the children. In zsh's ksh, you may overwrite TTY but exporting it has no effect. It's reset by the shell in each new child. (a kind person on this list point These scripts, and a lot of application code, were written under sh where there is no built-in $TTY. Probably that particular thing will never bother you, but can you really imagine that there are no other such land mines?

And I would definitely not have that detect /usr/local/bin/zsh code added to the scripts. Just put the real ksh in path and wherever else the bang-lines expect it.

You will need to deal with differences in the various system commands though. Some have a fallback mode where they recognize traditional options even though they are not the normally correct options, that may be good enough, like ps will do "ps -ef" and lp will do "lp -dprintername" Some are simply naturally compatible enough because most of the differences are in the form of extensions & enhancements that don't break backwards compatibilty with older traditional versions. Like sed and awk both have more commands and can accept very large (unlimited? binary data too?) input records, but that doesn't hurt you if your code already works under older ones.
So you might not have too much grief on that score.
But then there are even dumber things. I have a couple of much-used scripts that have to react to uname so that they can use different command line options for "sort" of all things :)

Sometimes I deal with this by putting say "gfind ...|gxargs ..." instead of "find ... xargs" in a script and seeing to it that gnu find & xargs is installed on every box, since it's available on all platforms. and /usr/local/bin/gfoo on a SCO/Solaris/HP box doesn't harm anything that depends on "foo" being the stock foo, and it's trivial to make symlinks on linux/bsd boxes from gfoo to foo. It's better than maintaining multiple versions of scripts that each only work on one platform, and better than trying to put a lot of brains into scripts so that they can do different things on different platforms.

That same theory also could be an argument for switching over to bash or zsh across the board instead of trying to use zsh on linux and ksh on HP/UX. Rather than have /bin/ksh that might behave any of at least 4 ways (ksh88, ksh93, pdksh, zsh) write new scripts in zsh explicitly and see to it that zsh is installed everywhere. I did that, and I hate to admit it on the zsh mail list but did it with ksh93 not zsh. my scripts have "#!/bin/ksh93" at the top. It's simpler to put a binary or a symlink to an existing binary on each box than to hack up and then maintain all the scripts.


Brian K. White  --  brian@xxxxxxxxx  --  http://www.aljex.com/bkw/
+++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++.
filePro  BBx    Linux  SCO  FreeBSD    #callahans  Satriani  Filk!



Put the following function after the "emulate ksh".  It doesn't
cover all possibilities but it should do the basics.  (It's annoying
there's apparently no way of rationalising the path to a directory without
changing into it.)

whence () {
 # Version of whence which expands the full path to an
 # executable.  Uses the builtin whence if the argument
 * is not found in the path.
 # N.B.: doesn't test if the argument matches an alias, builtin
 # or function first, unlike the builtin.
 local p f
 # Ensure pushd doesn't ignore duplicates,
 # and doesn't output messages
 emulate -L zsh
 setopt pushdsilent

 if [[ $1 != /* ]]; then
   for p in $path; do
     if [[ -x $p/$1 ]]; then
       f=$p/$1
# Temporarilly switch to the directory of the file found.
# This rationalises the directory path.
       pushd $f:h
       print $PWD/$f:t
       popd
       return
     fi
   done
 fi
 builtin whence $1
}

--
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


Your mail client is unable to display the latest news from CSR. To access our news copy this link into a web browser: http://www.csr.com/email_sig.html




Messages sorted by: Reverse Date, Date, Thread, Author