Op 24-07-20 om 10:47 schreef Geoff Clare:
Ksh93 doesn't turn off -m in a subshell, so testing SH_MONITOR wouldn't
prevent the job number output.  I think it should have a separate flag
to indicate when the shell is behaving non-interactively despite the -i
flag being set.

It depends on how you test it. ksh93 internally keeps track of (different aspects of) job control in three different ways:

        sh_isoption(SH_MONITOR) // the actual shell option
        sh_isstate(SH_MONITOR)  // internal state flag
        job.jobcontrol          // global state variable

I'm not sure what the difference is between the latter two. When ksh tests for job control, sometimes it uses sh_isstate(), sometimes the global variable, and there seems to be no rhyme or reason re which is used when. I do know that ksh93 job control behaviour is broken in a few ways, although it remains to be clarified how exactly.

Currently, ksh tests for sh_isstate(SH_INTERACTIVE) to decide whether to output the job number. Adding '&& sh_isstate(SH_MONITOR)' prevents it from outputting the job number in non-forked subshells, even if the -m option is active in them.

Bash and dash also don't turn off -m, as reported by set +o, so your
claim that most shells "disable" job control is not correct in that regard.

At least on ksh93, the state of the -m shell option is not all that relevant for subshells. Most shells (mksh being the exception) don't turn off the -i option in subshells either, yet subshells act non-interactively.

ksh93 job control is also broken in other ways, as you can see from your own
"<command unknown>" output. I'm currently trying to fix it. It disables job
control in command substitutions but not in non-forked non-comsub subshells,
causing several different kinds of misbehaviour.

It doesn't turn off -m in command substitutions:

$ echo $(set +o) | grep monitor
set --default --bgnice --braceexpand --monitor --multiline --vi --viraw

Obviously that's a good thing since the point of set +o is to be
able to obtain the option settings to restore them later.

True. However, ksh93 has explicit code for disabling job control in command substitutions. It changes the SH_MONITOR state flag and the job.jobcontrol variable, but not the shell option.

A proper test for job control is whether you can use the 'fg' command

The fg command is a feature of interactive job control. There is no
reason why anyone would want to use it in an (effectively or actually)
non-interactive shell environment.

Does POSIX specify that job control behaves differently for interactive shells vs. (non-interactive shells or subshells)? If so, where?

[...]
It is only the interactive aspects of job control that are not available
in a subshell.  The parts that still work (in particular process group
ID assignment and the ability to send a signal to that process group
using kill %%) are still available and useful.

But ksh 93u+ 2012-08-01 does not do this either (note the extra '; :' is needed to avoid optimising the subshell away when using '-c'):

$ /bin/ksh -c 'set -m; (/bin/sleep 2 & ps -o pid,pgid,command); :'
  PID  PGID COMMAND
24570 24570 ksh -c set -m; (/bin/sleep 2 & ps -o pid,pgid,command); :
24571 24570 ksh -c set -m; (/bin/sleep 2 & ps -o pid,pgid,command); :
24572 24570 /bin/sleep 2

However, an "interactive" shell (-i flag, which implies -m) does create a process group:

$ /bin/ksh -i -c '(/bin/sleep 2 & ps -o pid,pgid,command); :'
[1]     24636
  PID  PGID COMMAND
24634 24634 /bin/ksh -i -c set -m; (/bin/sleep 2 & ps -o pid,pgid,command); exit 24635 24635 /bin/ksh -i -c set -m; (/bin/sleep 2 & ps -o pid,pgid,command); exit
24636 24635 /bin/sleep 2

So, would you say that ksh93's behaviour with just -m is broken (as in POSIX non-compliant) and needs fixing?

At least, ksh93 is the odd one out here. By my testing, other shells (bash, dash, mksh, yash, zsh) do act as you suggest, even when adding the '; :'.

- Martijn

--
||      modernish -- harness the shell
||      https://github.com/modernish/modernish
||
||      KornShell lives!
||      https://github.com/ksh93/ksh

Reply via email to