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>

Attachment: pgpOSR5NFRIpp.pgp
Description: OpenPGP Digital Signature

Reply via email to