Re: $? behaviour after comsub in same command

2023-04-11 Thread Chet Ramey via austin-group-l at The Open Group

On 4/10/23 7:02 PM, Robert Elz wrote:

 Date:Mon, 10 Apr 2023 10:30:08 -0400
 From:Chet Ramey 
 Message-ID:  <78038281-f431-775e-6d60-a44126d1d...@case.edu>

   | The different semantics are that the standard specifies the status of the
   | simple command in terms of the command substitution that's part of the
   | assignment statement, so you have to hang onto it for a while.

I suspect that's because you are treating the assignments (more or less)
as statements of their own, and expanding and then assigning each, one by one,
left to right as you encounter them.


No, the sentence means exactly what it says. The difference between his
example and mine is that in my example the shell has to remember the return
status of the last command substitution until the command completes.



then there is no issue, and no real need to "hang onto it for a while".


Of course you do, the standard says it's the return status of the command.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: $? behaviour after comsub in same command

2023-04-10 Thread Robert Elz via austin-group-l at The Open Group
Date:Mon, 10 Apr 2023 10:30:08 -0400
From:Chet Ramey 
Message-ID:  <78038281-f431-775e-6d60-a44126d1d...@case.edu>

  | The different semantics are that the standard specifies the status of the
  | simple command in terms of the command substitution that's part of the
  | assignment statement, so you have to hang onto it for a while.

I suspect that's because you are treating the assignments (more or less)
as statements of their own, and expanding and then assigning each, one by one,
left to right as you encounter them.

If you treated several var assigns just like they were args to commands,
expanded them all (for this purpose, left to right) and then run the
command - which involves putting the values to be assigned from var-assigns
into the environment of the command to be run ... in this case, the null
command, so that means the assignments affect the current shell environment,
then there is no issue, and no real need to "hang onto it for a while".

In the case where there's no command, the exit status of the last cmdsub
is simply there, for the next command to use (not this one, because there
are no more expansions to be made) - in the case where there is a command
the command execution comes next, and the exit status from that overrides
the exit status from the command substitution, before there is any possibility
of the cmdsub status (for the one that might matter, or any earlier ones
that might also have been executed, which are already lost) become visible,
to anything, as no more expansions are happening at this point.

But because the standard doesn't actually say which order these things need
to be evaluated, but does say how $? is supposed to be affected, the
implementations can get messy to handle all of this properly, if the
implementation chooses a different way of handling the unspecified part
(which really, is unspecified just because some early implementations did that).

Note, that before we do any of this (var-assign, and redirect, processing)
we have already expanded all the rest of the command line, the words that are
not related to redirects or var-assigns, we have the command name (if any)
and know if it is there at all (or not, a null command) and if it is a
built-in of some kind (so whether or not we shall fork() ... create a new
shell environment) or not - and if we want, when there is to be one, most
of the rest (redirects and var-assigns) can be expanded in that new
environment (in the child process).  Or not.   That's all just implementation
detail (provided we don't leave any inappropriate results in the parent
shell environment .. which means special care if the fork() is implemented
using vfork()).

kre



Re: $? behaviour after comsub in same command

2023-04-10 Thread Chet Ramey via austin-group-l at The Open Group

On 4/6/23 5:59 PM, Robert Elz wrote:

 Date:Wed, 5 Apr 2023 10:35:58 -0400
 From:"Chet Ramey via austin-group-l at The Open Group" 

 Message-ID:  

   | A variant with slightly different semantics:
   |
   | (exit 8)
   | a=4 b=$(exit 42) c=$?
   | echo status:$? c=$c
   |
   | The standard is clear about what $? should be for the echo, but should it
   | be set fron the command substitution for the assignment to c?

It isn't really different semantics, it is the same thing.


The different semantics are that the standard specifies the status of the
simple command in terms of the command substitution that's part of the
assignment statement, so you have to hang onto it for a while.

We have this identical discussion every couple of years. At least the last
time produced interp 1150, which -- in true standards fashion -- attempted
to clarify the issue with additional obscure language.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: $? behaviour after comsub in same command

2023-04-10 Thread Chet Ramey via austin-group-l at The Open Group

On 4/6/23 5:43 PM, Robert Elz wrote:


Hence we got that absurd PATH search rule for builtins, that no shell of
the time did anything like, "because a user might want to override a
builtin with a version in their own bin directory, earlier in PATH than
where the standard version of the command exists",


Yes, it's ludicrous and ahistorical, but you still had people arguing in
favor of it as recently as a few years ago. There were proposals to extend
(abuse?) env, exec, and command to accomplish the task of temporarily
overriding a builtin, but those place the burden on the script author
rather than enable the user to do it.

The bash `enable' builtin is always used as the canonical example, since
there's printer (I think) software that uses it as a command name.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: $? behaviour after comsub in same command

2023-04-06 Thread Robert Elz via austin-group-l at The Open Group
Date:Fri, 7 Apr 2023 05:38:16 +0300
From:=?UTF-8?B?T8SfdXo=?= 
Message-ID:  


  | a=${b#prefix} a=${a%suffix}
  |
  | is common enough a pattern to consider despite having no benefit other than
  | looking organized. Most shells interpret it the way average user would
  | expect too

Most might, but it is still unspecified (and is not something I think I
have ever encountered).   It is trivial to fix by putting a ';' or newline
between the two assignments, then it works everywhere.  Why wouldn't you?

And what's more, tell the authors of anyone else making this mistake that
it is unspecified, and how simple it is to fix.

kre

ps: replying only to the list, as gmail simply bounces any messages I
send to its users directly.



Re: $? behaviour after comsub in same command

2023-04-06 Thread Oğuz via austin-group-l at The Open Group
7 Nisan 2023 Cuma tarihinde Robert Elz via austin-group-l at The Open Group
 yazdı:

> My guess (no more than that) is that sometimes it is easier to
> give in to the desires of the masses rather than maintain the
> correct approach.
>
> To people who don't understand sh syntax,
>
> a=1 b=2 c=3
>
> kind of looks like 3 commands that should be executed in order
> as written, just like
>
> a=1
> b=2
> c=3
>
> would be.
>

Yeah.

a=${b#prefix} a=${a%suffix}

is common enough a pattern to consider despite having no benefit other than
looking organized. Most shells interpret it the way average user would
expect too


-- 
Oğuz


Re: $? behaviour after comsub in same command

2023-04-06 Thread Robert Elz via austin-group-l at The Open Group
Date:Fri, 07 Apr 2023 03:14:47 +0200
From:Steffen Nurpmeso 
Message-ID:  <20230407011447.ptyvc%stef...@sdaoden.eu>

  | There i say

I'll omit the quotes from the standard...

  |   So everything should be handled sequentially, making it a bug.

>From where do you get sequentially?  I don't see that anywhere.

And sequential what?  And where do you see whatever that is specified?

  | And that is true, no?  If expansion has to take place, and the
  | assignment has been performed, .. it has been performed?

Sure, but the normal way to evaluate any command (omitting
irrelevant aspects here, like redirects, etc) is to evaluate
all the words (perform expansions) and then execute it.

Why would evaluating var assigns be any different?  Expand all the
words, then execute (assign).  Seems to me like the obvious (and
correct) way.

  | So maybe null command and that is not a bug?

No, I don't think it is.

  | But all shells except FreeBSD do this; also from the report:

NetBSD too, and according to reports, dash only just changed.

My guess (no more than that) is that sometimes it is easier to
give in to the desires of the masses rather than maintain the
correct approach.

To people who don't understand sh syntax,

a=1 b=2 c=3

kind of looks like 3 commands that should be executed in order
as written, just like

a=1
b=2
c=3

would be.  But the first form isn't 3 commands, it is one.
There is nothing there (except the final newline) which is
a command terminator.

Note here that I am not claiming that shells which do it the
"other" way are non-conforming, about all the standard says
is that the words need to be expanded before the assignment
is performed - it doesn't say to expand all the words, then
do assignments, it doesn't say expand each word and then
assign, and then go on to the next, and it doesn't say which
order to do the expansions or assignments (left to right, right
to left, or random).

That means that all of that is unspecified, and shells can
do it in whatever order makes sense to them.  I have my own
views on what is best here, and won't be changing the NetBSD
sh from how it behaves in this area.  I hope FreeBSD don't
change either.

It alsp means that applications that use any of this unspecified
behaviour, expecting some particular result, are broken, and
cannot legitimately complain when some shell doesn't work the
way they expect.  It doesn't mean they won't, unfortunately.

kre



Re: $? behaviour after comsub in same command

2023-04-06 Thread Steffen Nurpmeso via austin-group-l at The Open Group
Robert Elz wrote in
 <6906.1680741...@jacaranda.noi.kre.to>:
 ...
 |The issue here is that people tend to think of
 | a=1
 |as a command.   It isn't (not as people think of it anyway).
 |But with that mindset they treat
 | a=1 b=$a c=$b
 |as 3 commands, one after the other.   It isn't.

To come back to the bug i reported to FreeBSD ([1]).

  [1] https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251770

There i say

  3385   4.23Variable Assignment
  3386   In the shell command language, a word consisting of the 
following parts:
  3387   varname=value
  3388   When used in a context where assignment is defined to 
occur and at no other time, the value
  3389   (representing a word or field) shall be assigned as the 
value of the variable denoted by varname.
  3390   Note:  For further information, see XCU Section 
2.9.1 (on page 2365).

  ---

  75482   2.9.1Simple Command

  754954.Each variable assignment shall be expanded for 
tilde expansion, parameter expansion,
  75496  command substitution, arithmetic expansion, 
and quote removal prior to assigning the
  75497  value.

  ---

  75501  Variable assignments shall be performed as follows:
  75502 •   If no command name results, variable assignments shall 
affect the current execution
  75503 environment.

  ---

  So everything should be handled sequentially, making it a bug.

And that is true, no?  If expansion has to take place, and the
assignment has been performed, .. it has been performed?

  ---

  75504 •   If the command name is not a special built-in utility 
or function, the variable assignments
  [.]
  75507 4. In this case it is unspecified:
  75508   — Whether or not the assignments are visible for 
subsequent expansions in step 4
  75509   — Whether variable assignments made as side-effects 
of these expansions are visible for
  75510 subsequent expansions in step 4, or in the current 
shell execution environment, or
  75511 both

  ---

  So it allows to setup the "execution environment of the command" entirely 
from the current environment, which is effectively read-only.  As you say.

So maybe null command and that is not a bug?
But all shells except FreeBSD do this; also from the report:

  #?2|kent$ for s in dash bash mksh bosh; do $s -c 'du=ich wir='"'"'hey 
'"'"'$du; echo $wir'; done
  hey ich
  hey ich
  hey ich
  hey ich

I am no shell expert whatsoever.  My mailer will never support
that (except for assignment in arithmetic expression eg $((i=1))):

 This behaviour is different to the SHELL[644], which is a programming
 language with syntactic elements of clearly defined semantics, and there‐
 fore capable to sequentially expand and evaluate individual elements of a
 line.  ‘? set one=spoon two=$one’ for example will never assign ‘spoon’
 to two, because it is the command set[275] that performs the assignment,
 long after the expansion has happened.

So i am out.

--steffen
|
|Der Kragenbaer,The moon bear,
|der holt sich munter   he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



Re: $? behaviour after comsub in same command

2023-04-06 Thread Harald van Dijk via austin-group-l at The Open Group
On 05/04/2023 18:05, Harald van Dijk via austin-group-l at The Open 
Group wrote:

On 05/04/2023 17:44, Oğuz wrote:
5 Nisan 2023 Çarşamba tarihinde Harald van Dijk > yazdı:


    I am not sure which other ash based shells you were looking at,
/bin/sh on NetBSD and FreeBSD


Thanks. I indeed see the same results as you on a recent version of 
FreeBSD sh (the one on the FreeBSD 13.1 installation media).


There is a legitimate benefit to this: swapping variables without an 
additional helper variable actually works in that implementation.


   a=1 b=2
   a=$b b=$a
   echo $b $a


Actually, I am seeing another legitimate benefit:

The standard is clear that in

  export a="$b" b="$a"

the arguments to the 'export' command are expanded first, and then the 
'export' command is run which performs the assignments, thus swapping 
the values of 'a' and 'b', but also exporting their values.


It seems rather a shame that

  export a=<...> b=<...>

and

  a=<...> b=<...>
  export a b

do not have the same effect, so that the 'export a b' line can be taken 
out when exporting is not desired. Under the traditional ash behaviour, 
these do have the same effect. This consistency, to me, is a good 
argument in favour of the traditional behaviour and in favour of POSIX 
permitting that behaviour.


Cheers,
Harald van Dijk



Re: $? behaviour after comsub in same command

2023-04-06 Thread Robert Elz via austin-group-l at The Open Group
Date:Wed, 5 Apr 2023 10:35:58 -0400
From:"Chet Ramey via austin-group-l at The Open Group" 

Message-ID:  

  | A variant with slightly different semantics:
  |
  | (exit 8)
  | a=4 b=$(exit 42) c=$?
  | echo status:$? c=$c
  |
  | The standard is clear about what $? should be for the echo, but should it
  | be set fron the command substitution for the assignment to c?

It isn't really different semantics, it is the same thing.   The exit status
from the command substitution in that case is used as the exit status for the
empty command that is line 2 (you're right, that is clear).  But that command
doesn't get to set an exit status until it finishes, and it can't do that
until its associated var assigns have all been performed, which (even
leaving aside the question of the order in which they, and the args for
them, are processed) cannot possibly be before c=$? is expanded and assigned.

Needless to say, the same (exact) set of shells which produced N:N in the
example in my previous message, set c to 42, and all the rest (including
the older ksh93) set c to 8 (which really is what it should be - the other
possibility here would be "unspecified" as even if the exit status were to
become available in the middle of evaluating the args for a command, here
we don't know whether c= or b= will be evaluated first.

All the standard actually says is:

4. Each variable assignment shall be expanded for tilde expansion,
   parameter expansion, command substitution, arithmetic expansion,
   and quote removal prior to assigning the value.

There's nothing there about the order in which they're processed (unlike,
for example, redirects, which are required to be process left to right)
which makes the order implicitly unspecified.   Anything is possible.

But as, in any sane implementation, assigning the values to the variables
should not in any way affect the values assigned to other variables in the
same set of var assigns, it really should not matter the order in which
they're processed, unless someone is idiotic enough to write

   a=1 a=2 a=3

in which case what value gets left in a is anyone's guess, and they get
what they deserve.

kre





Re: $? behaviour after comsub in same command

2023-04-06 Thread Robert Elz via austin-group-l at The Open Group
Date:Thu, 6 Apr 2023 11:17:43 -0400
From:"Chet Ramey via austin-group-l at The Open Group" 

Message-ID:  <023c0028-e682-e1b6-99db-c8a596cdf...@case.edu>

  | My question is why they would choose something other than
  | what the so-called reference implementations (SVR4 sh, ksh88) did.

Not that I was participating at the time, so I have no actual knowledge
of any of this, but I get the impression that back then it was considered
OK to change things if the group believed it "made it better for the users".

Hence we got that absurd PATH search rule for builtins, that no shell of
the time did anything like, "because a user might want to override a
builtin with a version in their own bin directory, earlier in PATH than
where the standard version of the command exists", or the even stupider
(and fortunately, going to be gone) rule that all the normal built-in
commands needed to be available in the file system (not so much so the
preceding PATH rule would allow them to be overridden - that didn't work
in practice anyway, but in case someone wants to "nohup cd" or
"find ... -exec umask whatever".   Nonsense.)

This is likely more of the same - but in this case I actually agree
with it - $? only gets updated when a command finishes, and only one
in the current execution environment.   That's clear, simple, and
easy to use - otherwise using $? other than as S=$? immediately after
the command whose status is of interest, becomes a total crap shoot.

That's reinforced in this case, by wording that makes it clear that the
only way to ever observe the exit status from a command in a command
substitution (other than the command there writing the value of its $?
somewhere) is to run it with a null command (just a var-assign, or
redirect).   That is, when there is no command, the status of the last
command substitution (if any) becomes $?.   That's the only way.

Otherwise things like

return $(true)

would need to work (as an equiv of return 0 - and return $(false) for
return 1 - and the standard as never required that).

Given:
 $SHELL -c 'f() { return $( exit $1 ); }; e() { for A; do f "$A"; echo 
"$A:$?"; done; }; e 0 1 2 3 99'

which I will unwrap to make it easier to read:

 $SHELL -c '
f() {
return $( exit $1 );
};
e() {
for A;
do
f "$A";
echo "$A:$?";
done;
};
e 0 1 2 3 99
'

bash, zsh, and a current ksh93 (Version AJM 93u+m/1.0.4 2022-10-22)
actually print N:N for all of the output lines, whereas everything else
I tested, including an older ksh93 (Version AJM 93u+ 2012-08-01) and
ancient pdksh, prints N:0 for everything.   Since the return is effectively
"return" (the command substitution doesn't output anything - if it were
$( echo $1 )
instead of exit $1 things would be different) it should return with the
status of the last command to finish - which here is always either 0,
from the status set by the function definition for e (the very first time)
or the result from the "echo" after the previous iteration, every other time.
Since echo's status is (generally, and always here) 0, the return should
always be "return 0").

kre

ps: all this is really esoteric, and makes no real difference to any
sane application.





Re: $? behaviour after comsub in same command

2023-04-06 Thread Harald van Dijk via austin-group-l at The Open Group

On 06/04/2023 20:03, Chet Ramey via austin-group-l at The Open Group wrote:

On 4/6/23 1:55 PM, Harald van Dijk wrote:

One additional data point: in schily-2021-09-18, Jörg's last release, 
obosh, the legacy non-POSIX shell that is just there for existing 
scripts and for portability testing, prints 0 (using `` rather than 
$()), whereas pbosh and sh, the minimal and extended POSIX versions of 
the shell, print 1. This does provide extra support for the view that 
this was a change that POSIX demanded, that the deviation from 
historical practice was intentional, but does not answer what the 
reasoning might have been.


I doubt it was `demanded'; the bosh change immediately followed an austin-
group discussion (we both participated) about this exact issue. Maybe he
thought it was the right thing based on that discussion.


Possibly something lost in translation here. What I meant by "that POSIX 
demanded" was just "that was intended to be required for POSIX conformance".



As part of the discussion, he wrote:

 > The important thing to know here is that the Bourne Shell has some
 > checkpoints that update the intermediate value of $?. Since that 
changed in
 > ksh88 and since POSIX requires a different behavior compared to the 
Bourne

 > Shell, I modified one checkpoint in bosh to let it match POSIX.

so he had already been modifying that behavior before 2021, maybe after
interp 1150.


And again. I can see how you would read my message as saying that this 
is something he changed in his last release. That wasn't what I was 
going for, I only meant that his last release was the one that I tested. 
It did not seem relevant to test all earlier versions to figure out when 
this changed.


Cheers,
Harald van Dijk



Re: $? behaviour after comsub in same command

2023-04-06 Thread Chet Ramey via austin-group-l at The Open Group

On 4/6/23 1:55 PM, Harald van Dijk wrote:

One additional data point: in schily-2021-09-18, Jörg's last release, 
obosh, the legacy non-POSIX shell that is just there for existing scripts 
and for portability testing, prints 0 (using `` rather than $()), whereas 
pbosh and sh, the minimal and extended POSIX versions of the shell, print 
1. This does provide extra support for the view that this was a change that 
POSIX demanded, that the deviation from historical practice was 
intentional, but does not answer what the reasoning might have been.


I doubt it was `demanded'; the bosh change immediately followed an austin-
group discussion (we both participated) about this exact issue. Maybe he
thought it was the right thing based on that discussion.

As part of the discussion, he wrote:

> The important thing to know here is that the Bourne Shell has some
> checkpoints that update the intermediate value of $?. Since that changed in
> ksh88 and since POSIX requires a different behavior compared to the Bourne
> Shell, I modified one checkpoint in bosh to let it match POSIX.

so he had already been modifying that behavior before 2021, maybe after
interp 1150.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: $? behaviour after comsub in same command

2023-04-06 Thread Harald van Dijk via austin-group-l at The Open Group

On 06/04/2023 16:17, Chet Ramey wrote:

On 4/5/23 12:36 PM, Harald van Dijk wrote:
On 05/04/2023 15:35, Chet Ramey via austin-group-l at The Open Group 
wrote:
On 4/5/23 9:06 AM, Martijn Dekker via austin-group-l at The Open 
Group wrote:

Consider:

 false || echo $(true) $?

dash, mksh and yash print 1.
bash, ksh93 and zsh print 0.
Which is right?


I believe dash, mksh, yash are already right based on the current 
wording of the standard. As Martijn wrote, the rule is that $? 
"Expands to the decimal exit status of the most recent pipeline", the 
most recent pipeline in the shell environment in which $? is evaluated 
is "false", and changes in the subshell environment shall not affect 
the parent shell environment, including changes in the subshell 
environment to $?.


That's certainly one interpretation, and may indeed be what the 1992
authors intended. My question is why they would choose something other than
what the so-called reference implementations (SVR4 sh, ksh88) did.


That is a good question that I have no answer for.

One additional data point: in schily-2021-09-18, Jörg's last release, 
obosh, the legacy non-POSIX shell that is just there for existing 
scripts and for portability testing, prints 0 (using `` rather than 
$()), whereas pbosh and sh, the minimal and extended POSIX versions of 
the shell, print 1. This does provide extra support for the view that 
this was a change that POSIX demanded, that the deviation from 
historical practice was intentional, but does not answer what the 
reasoning might have been.


Cheers,
Harald van Dijk



Re: $? behaviour after comsub in same command

2023-04-06 Thread Chet Ramey via austin-group-l at The Open Group

On 4/5/23 12:36 PM, Harald van Dijk wrote:

On 05/04/2023 15:35, Chet Ramey via austin-group-l at The Open Group wrote:
On 4/5/23 9:06 AM, Martijn Dekker via austin-group-l at The Open Group 
wrote:

Consider:

 false || echo $(true) $?

dash, mksh and yash print 1.
bash, ksh93 and zsh print 0.
Which is right?


I believe dash, mksh, yash are already right based on the current wording 
of the standard. As Martijn wrote, the rule is that $? "Expands to the 
decimal exit status of the most recent pipeline", the most recent pipeline 
in the shell environment in which $? is evaluated is "false", and changes 
in the subshell environment shall not affect the parent shell environment, 
including changes in the subshell environment to $?.


That's certainly one interpretation, and may indeed be what the 1992
authors intended. My question is why they would choose something other than
what the so-called reference implementations (SVR4 sh, ksh88) did.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: $? behaviour after comsub in same command

2023-04-06 Thread Oğuz via austin-group-l at The Open Group
5 Nisan 2023 Çarşamba tarihinde Harald van Dijk  yazdı:

> There is a legitimate benefit to this: swapping variables without an
> additional helper variable actually works in that implementation.


Good point, thanks


-- 
Oğuz


Re: $? behaviour after comsub in same command

2023-04-05 Thread Robert Elz via austin-group-l at The Open Group
Date:Wed, 5 Apr 2023 18:25:32 +0300
From:"=?UTF-8?B?T8SfdXo=?= via austin-group-l at The Open Group" 

Message-ID:  


  | Outliers are ash based shells; they apply
  | assignments concurrently but it isn't useful at all.

No we don't, to do it concurrently we'd need to run multiple threads,
and synchronise them carefully, and we don't...

What we do is separate the process of doing the expansions from doing
the execution of any command.   The expansions happen first, the rest
comes after.

The issue here is that people tend to think of
a=1
as a command.   It isn't (not as people think of it anyway).
But with that mindset they treat
a=1 b=$a c=$b
as 3 commands, one after the other.   It isn't.

The simple
a=1
case is a null command, with a var-assign prepended.
The other case
a=1 b=$a c=$b
is also a (single) null command, this time with 3 var-assigns
prepended.

If you want sequential execution, that's easy to achieve, just
change
a=1 b=$a c=$b
into
a=1;b=$a;c=$b
then you have 3 null commands, each with a single var-assign,
and those will be executed, in order, one at a time, just like
you want the other one to be, in any shell that isn't completely
broken.

As reported in a later message, the "isn't useful at all" is
wrong, as doing the expansions first, and then the assignments
later, when it is all part of the same command (whether a null
command or just var-assigns preceding any other command) means
that
a=$b b=$a
does work to swap a and b, and doesn't require creating a new
var, which in a case like

t=$a a=$b b=$t command

would result in placing t into the environment for command, which
might be harmless, or might not be if you happened to accidentally
pick the wrong temporary name to use.

a=$b b=$a command

doesn't do that, it just puts a and b (as desired) in the environment,
and works sensibly.

That it works exactly the same way when command is missing, would, I
would have thought, be expected.   It is the right way.

We don't need two different ways to achieve a=1;b=$a;c=$b that one
is quite sufficient.   Just use it.

kre



Re: $? behaviour after comsub in same command

2023-04-05 Thread Steffen Nurpmeso via austin-group-l at The Open Group
Steffen Nurpmeso wrote in
 <20230405193451.u9bfz%stef...@sdaoden.eu>:
 |Harald van Dijk wrote in
 | <32a27194-a5ff-68d6-3a87-9120e34d8...@gigawatt.nl>:
 ||On 05/04/2023 17:44, Oğuz wrote:
 ||> 5 Nisan 2023 Çarşamba tarihinde Harald van Dijk  > yazdı:
 ||> 
 ||> I am not sure which other ash based shells you were looking at, 
 ||> 
 ||> /bin/sh on NetBSD and FreeBSD
 ||
 ||Thanks. I indeed see the same results as you on a recent version of 
 ||FreeBSD sh (the one on the FreeBSD 13.1 installation media).
 ||
 ||There is a legitimate benefit to this: swapping variables without an 
 ||additional helper variable actually works in that implementation.
 ||
 ||   a=1 b=2
 ||   a=$b b=$a
 ||   echo $b $a
 ||
 ||As it turns out, the at the moment still rather incomplete mrsh 
 || also behaves this way.
 |
 |I think i have open(ed) a bug tracker item on that in the past.
 |Ah yes, their bugzilla says
 |
 |  https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251770

That is the above is about sequential workings of assignments/etc
on a line, nothing else (i have not really tracked this thread as
it is much too specific on sh internals).

--steffen
|
|Der Kragenbaer,The moon bear,
|der holt sich munter   he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



Re: $? behaviour after comsub in same command

2023-04-05 Thread Steffen Nurpmeso via austin-group-l at The Open Group
Harald van Dijk wrote in
 <32a27194-a5ff-68d6-3a87-9120e34d8...@gigawatt.nl>:
 |On 05/04/2023 17:44, Oğuz wrote:
 |> 5 Nisan 2023 Çarşamba tarihinde Harald van Dijk  > yazdı:
 |> 
 |> I am not sure which other ash based shells you were looking at, 
 |> 
 |> /bin/sh on NetBSD and FreeBSD
 |
 |Thanks. I indeed see the same results as you on a recent version of 
 |FreeBSD sh (the one on the FreeBSD 13.1 installation media).
 |
 |There is a legitimate benefit to this: swapping variables without an 
 |additional helper variable actually works in that implementation.
 |
 |   a=1 b=2
 |   a=$b b=$a
 |   echo $b $a
 |
 |As it turns out, the at the moment still rather incomplete mrsh 
 | also behaves this way.

I think i have open(ed) a bug tracker item on that in the past.
Ah yes, their bugzilla says

  https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251770

--steffen
|
|Der Kragenbaer,The moon bear,
|der holt sich munter   he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



Re: $? behaviour after comsub in same command

2023-04-05 Thread Harald van Dijk via austin-group-l at The Open Group

On 05/04/2023 17:44, Oğuz wrote:
5 Nisan 2023 Çarşamba tarihinde Harald van Dijk > yazdı:


I am not sure which other ash based shells you were looking at, 


/bin/sh on NetBSD and FreeBSD


Thanks. I indeed see the same results as you on a recent version of 
FreeBSD sh (the one on the FreeBSD 13.1 installation media).


There is a legitimate benefit to this: swapping variables without an 
additional helper variable actually works in that implementation.


  a=1 b=2
  a=$b b=$a
  echo $b $a

As it turns out, the at the moment still rather incomplete mrsh 
 also behaves this way.


Cheers,
Harald van Dijk



Re: $? behaviour after comsub in same command

2023-04-05 Thread Oğuz via austin-group-l at The Open Group
5 Nisan 2023 Çarşamba tarihinde Harald van Dijk  yazdı:

> I am not sure which other ash based shells you were looking at,


/bin/sh on NetBSD and FreeBSD


-- 
Oğuz


Re: $? behaviour after comsub in same command

2023-04-05 Thread Harald van Dijk via austin-group-l at The Open Group

On 05/04/2023 16:25, Oğuz via austin-group-l at The Open Group wrote:
5 Nisan 2023 Çarşamba tarihinde Chet Ramey via austin-group-l at The 
Open Group > yazdı:


but should it
be set fron the command substitution for the assignment to c? 



I think it'd be practical, is there a reason why it shouldn't? And while 
we're at it, is there a reason why assignments in a simple command 
shouldn't be applied sequentially, from left to right? Most shells 
already do it that way; that is,


     a=1 b=$a c=$b
     echo $a $b $c

prints `1 1 1' in them. Outliers are ash based shells; they apply 
assignments concurrently but it isn't useful at all.


Note that in dash, this only applies to older versions. dash 0.5.7 
(released in 2011) and higher print "1 1 1" like almost all other 
shells, and other dash-derived shells (busybox ash, and my own) keep it 
that way.


I am not sure which other ash based shells you were looking at, but it 
may be worth making sure you are on a current version.


Cheers,
Harald van Dijk



Re: $? behaviour after comsub in same command

2023-04-05 Thread Harald van Dijk via austin-group-l at The Open Group

On 05/04/2023 15:35, Chet Ramey via austin-group-l at The Open Group wrote:
On 4/5/23 9:06 AM, Martijn Dekker via austin-group-l at The Open Group 
wrote:

Consider:

 false || echo $(true) $?

dash, mksh and yash print 1.
bash, ksh93 and zsh print 0.
Which is right?


I believe dash, mksh, yash are already right based on the current 
wording of the standard. As Martijn wrote, the rule is that $? "Expands 
to the decimal exit status of the most recent pipeline", the most recent 
pipeline in the shell environment in which $? is evaluated is "false", 
and changes in the subshell environment shall not affect the parent 
shell environment, including changes in the subshell environment to $?.



A variant with slightly different semantics:

(exit 8)
a=4 b=$(exit 42) c=$?


Likewise, the most recent pipeline in the shell environment in which 
c=$? is evaluated is "(exit 8)", so c should be set to 8.



echo status:$? c=$c


Here, as shells agree, $? should expand to 42.


The standard is clear about what $? should be for the echo, but should it
be set fron the command substitution for the assignment to c?


The way the standard specifies that the final $? should expand to 42 is 
in 2.9.1 Simple Commands:


> [...] If there is no command name, but the command contained a 
command substitution, the command shall complete with the exit status of 
the last command substitution performed. Otherwise, the command shall 
complete with a zero exit status.


That is, the command substitution itself does not cause $? in the parent 
environment to change, rather it is the fact that the entire "a=4 
b=$(exit 42) c=$?" command exits with status 42 that causes $? to 
change. Nothing else in the standard indicates that the parent shell 
environment's $? value changes; while the expansion of the second 
command is in place, "the most recent pipeline" is still the previous one.


You have linked to  in 
a subsequent reply. This does not see the current wording as 
sufficiently clear, but does clear up with new wording that regardless 
of whether this can be inferred from the current wording of the 
standard, this interpretation is the intended one.


Cheers,
Harald van Dijk



Re: $? behaviour after comsub in same command

2023-04-05 Thread Chet Ramey via austin-group-l at The Open Group

On 4/5/23 11:25 AM, Oğuz wrote:
5 Nisan 2023 Çarşamba tarihinde Chet Ramey via austin-group-l at The Open 
Group mailto:austin-group-l@opengroup.org>> 
yazdı:


but should it
be set fron the command substitution for the assignment to c? 



I think it'd be practical, is there a reason why it shouldn't? 


https://www.austingroupbugs.net/view.php?id=1150

It's unspecified. The assignments are performed `beginning to end', but
it's not specified when $? is set. Interestingly, the SVR4 sh and ksh88
both set $? as each command substitution finishes, but POSIX didn't specify
that behavior explicitly. Maybe the 1992 authors didn't feel they had to.

And while
we're at it, is there a reason why assignments in a simple command 
shouldn't be applied sequentially, from left to right? 


The Bourne shell performed the assignments right to left. This came up on
the austin-group list a couple of years ago, in almost exactly the same
way, but I don't think the discussion made its way to an interpretation
request.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: $? behaviour after comsub in same command

2023-04-05 Thread Oğuz via austin-group-l at The Open Group
5 Nisan 2023 Çarşamba tarihinde Chet Ramey via austin-group-l at The Open
Group  yazdı:

> but should it
> be set fron the command substitution for the assignment to c?


I think it'd be practical, is there a reason why it shouldn't? And while
we're at it, is there a reason why assignments in a simple command
shouldn't be applied sequentially, from left to right? Most shells already
do it that way; that is,

a=1 b=$a c=$b
echo $a $b $c

prints `1 1 1' in them. Outliers are ash based shells; they apply
assignments concurrently but it isn't useful at all.



-- 
Oğuz


Re: $? behaviour after comsub in same command

2023-04-05 Thread Chet Ramey via austin-group-l at The Open Group

On 4/5/23 9:06 AM, Martijn Dekker via austin-group-l at The Open Group wrote:

Consider:

     false || echo $(true) $?

dash, mksh and yash print 1.
bash, ksh93 and zsh print 0.
Which is right?


A variant with slightly different semantics:

(exit 8)
a=4 b=$(exit 42) c=$?
echo status:$? c=$c

The standard is clear about what $? should be for the echo, but should it
be set fron the command substitution for the assignment to c?

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/