First off let me thank you for your very detailed reply! As I wrote in my other message yesterday I've given up entirely on trying to test for interactivity without using $-. It just doesn't matter for any shell supporting $ENV since they all do the right thing with $-.
I have discovered (by serendipity, having been reading the original Ash code to verify that it was setting $- with 'i' when necessary) that 's' is also set when the shell is reading from stdin, so for it testing for 's' in $-, and verifying stdin is a tty would also work to identify interactivity. Unfortunately that feature is not portable at all. The original Bourne shell actually puts 's' in $- even when given "-c command", and bosh continues this legacy. I don't know why it does this as it is entirely nonsensical. The original v7 manual doesn't document '-s'. From the code it looks like a bug: - options() notes and eats the '-c', and then returns the remaining number of arguments, which will be one. - main() turns on stdflg (the flag set by an explicit '-s' option argument) if options() returns less than 2, however since options() set comdiv to the '-c' parameter, it then sets things up to parse the string given and explicitly disables the input file descriptor (by setting it to -1). BTW, I see the original Bourne shell also tested stdin and _stdout_ when deciding if it was interactive or not. The change to test stderr must have come from AT&T Ksh. I see that's done as early as ksh88e, for example. At Thu, 10 Oct 2024 13:21:16 +0700, Robert Elz <k...@munnari.oz.au> wrote: Subject: Re: interactive shell detection in shrc > > > jacaranda$ sh -c 'echo $0' > sh > > and if the user desires, $0 can be made anything > > jacaranda$ sh -c 'echo $0' anything > anything Ah ha! I had forgotten about how '-c' works with extra arguments! Even more fun the third argument can look like an option letter, but still just ends up in argv[0]: $ sh -c 'echo $0' -i -i This is different from how rsh and ssh work. They are just stuffing all arguments into a single string to pass to the moral equivalent of system(3) (but using the remote user's shell instead of explicitly /bin/sh). I recall this difference being extremely confusing and frustrating to me as a novice, but since I've exploited it often to help avoid quoting hell with formatting complex commands for remote execution. (I think I wanted 'rsh' just be an extension of 'sh's command-line API, for reasons I don't remember.) > might work, about 1 time in 50. And that's ignoring the very real > possibility that test (aka [) might one day just say "test: too many args" > as (ignoring the ']' arg when argv[0] == '[') you have 6 args there, and > test (these days) is only defined to work with a maximum of 4 (and even > with 4, only when the first is '!' - otherwise 3 or less). This part confuses me.... The manual suggests '-a', '-o', and parenthesis can be used to create expressions of arbitrary length and complexity, and surely I've done so for decades with multitudes of implementations with nary a problem. I agree POSIX does only require support for 4 arguments, but with the XSI extension any number are allowed, but I've never met a POSIX-minimal only implementation of test(1). -- Greg A. Woods <gwo...@acm.org> Kelowna, BC +1 250 762-7675 RoboHack <wo...@robohack.ca> Planix, Inc. <wo...@planix.com> Avoncote Farms <wo...@avoncote.ca>
pgpOSR5NFRIpp.pgp
Description: OpenPGP Digital Signature