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 <kre%munnari.OZ.AU@localhost> 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 <gwoods%acm.org@localhost>
Kelowna, BC +1 250 762-7675 RoboHack <woods%robohack.ca@localhost>
Planix, Inc. <woods%planix.com@localhost> Avoncote Farms <woods%avoncote.ca@localhost>
Attachment:
pgpSkBzxvmwYx.pgp
Description: OpenPGP Digital Signature