"builtin jobs" does not output to stdout.

2023-02-11 Thread 岡部将幸
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2
uname output: Linux gold 5.8.0-63-generic #71-Ubuntu SMP Tue Jul 13
15:59:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.2
Patch Level: 15
Release Status: release

Description:
builtin command "jobs" behaves differntly depending on
the presence or absence of "builtin".
"jobs" outputs to stdout, but "builtin jobs" does not
output to stdout.

Repeat-By:
"sleep 1000 &"
"builtin jobs | cat" -> no output
"jobs | cat" -> [1]+ Running

Fix:
[Description of how to fix the problem.  If you don't know a
fix for the problem, don't include this section.]


Re: "builtin jobs" does not output to stdout.

2023-02-11 Thread Robert Elz
Date:Sat, 11 Feb 2023 22:54:47 +0900
From:=?UTF-8?B?5bKh6YOo5bCG5bm4?= 
Message-ID:  


  | "jobs" outputs to stdout, but "builtin jobs" does not
  | output to stdout.

Your test is flawed.   Processes in a pipeline are in a
subshell environment.  That environment has no jobs, hence
no output.

But there is a special exemption for that, when 'jobs'
is the first command in the subshell.  Then it reports
its parent's jobs table instead (this is to allow
j=$(jobs) to work mainly).

So jobs|whatever produces output, but builtin jobs|... does not.

To test whether builtin jobs writes to stdout, use

builtin jobs >/tmp/foo

instead.   No subshell there, so it should work.


Why would you want to ever say "builtin jobs" though?
The jobs command has to be buikt in to work.

kre




Re: "builtin jobs" does not output to stdout.

2023-02-11 Thread Koichi Murase
2023年2月11日(土) 23:57 岡部将幸 :
> Description:
> builtin command "jobs" behaves differntly depending on
> the presence or absence of "builtin".
> "jobs" outputs to stdout, but "builtin jobs" does not
> output to stdout.

This seems to be reproduced in all the Bash versions from 1.14.7 to
devel. The problem is related to the condition of whether subshell
builtins inherit the job information. In particular, this is related
to the following test in the source code [1]:

[1] https://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c?h=devel#n5236

$ sleep 1000 &
$ : | jobs
[1]+  Running sleep 1000 &
$ : | command jobs
[1]+  Running sleep 1000 &
$ echo "$(jobs)"
[1]+  Running sleep 1000 &

In these cases, the `jobs' builtin inherits the job information of the
main shell.

$ : | { jobs; }
$ (jobs)

In these cases, the `jobs' builtin shouldn't print the job information
of the main shell. So, the `jobs' builtin in subshells actually
inherits the job information only in a limited case, which is
implemented in [1]. Now we call the `jobs' builtin through the
`builtin' builtin in the reported code, so it bypasses the condition
tested in [1]. We can test many other combinations of such indirect
builtin calls, where it doesn't inherit the job information if at
least one `builtin' is contained in the chain:

$ : | command jobs
[1]+  Running sleep 1000 &
$ : | command command jobs
[1]+  Running sleep 1000 &
$ : | command command command jobs
[1]+  Running sleep 1000 &
$ : | builtin jobs
$ : | command builtin jobs
$ : | builtin builtin jobs
$ : | builtin command jobs
$ : | builtin builtin builtin jobs

--
Koichi



Re: "builtin jobs" does not output to stdout.

2023-02-11 Thread alex xmb ratchev
root@localhost:~# ( sleep .1 & jobs ) | wc -c
41

On Sat, Feb 11, 2023, 3:57 PM 岡部将幸  wrote:

> Configuration Information [Automatically generated, do not change]:
> Machine: x86_64
> OS: linux-gnu
> Compiler: gcc
> Compilation CFLAGS: -g -O2
> uname output: Linux gold 5.8.0-63-generic #71-Ubuntu SMP Tue Jul 13
> 15:59:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
> Machine Type: x86_64-pc-linux-gnu
>
> Bash Version: 5.2
> Patch Level: 15
> Release Status: release
>
> Description:
> builtin command "jobs" behaves differntly depending on
> the presence or absence of "builtin".
> "jobs" outputs to stdout, but "builtin jobs" does not
> output to stdout.
>
> Repeat-By:
> "sleep 1000 &"
> "builtin jobs | cat" -> no output
> "jobs | cat" -> [1]+ Running
>
> Fix:
> [Description of how to fix the problem.  If you don't know a
> fix for the problem, don't include this section.]
>


Re: "builtin jobs" does not output to stdout.

2023-02-11 Thread Koichi Murase
2023年2月12日(日) 0:42 Robert Elz :
> Why would you want to ever say "builtin jobs" though?
> The jobs command has to be buikt in to work.

`jobs' can be overwritten by a shell function. For example, when a
user wants to modify the behavior of `jobs' for interactive uses, a
typical solution is to override `jobs' with a shell function and call
`builtin jobs' in the overriding function.

I guessed you have asked this because `jobs' would be specified as a
special built-in utility [XCU 2.14], which cannot be hidden by a
shell-function name, but it doesn't seem to be the case actually;
`jobs' doesn't seem to be specified to be a special built-in utility.
Anyway, `jobs' can be hidden by a shell function at least in Bash.

I naively think that it is a valid request that `builtin jobs' would
behave in the same way as `jobs' in this context. POSIX also states
that the results are unspecified when the command name matches
`builtin' according to [XCU 2.9.1 / Command Search and Execution /
rule 1b].

--
Koichi



Re: "builtin jobs" does not output to stdout.

2023-02-11 Thread Robert Elz
Date:Sun, 12 Feb 2023 01:14:12 +0900
From:Koichi Murase 
Message-ID:  


  | `jobs' can be overwritten by a shell function. For example, when a
  | user wants to modify the behavior of `jobs' for interactive uses, a
  | typical solution is to override `jobs' with a shell function and call
  | `builtin jobs' in the overriding function.

The standard way to do that would be to use "command jobs" - but in either
of those cases, it is possible that the way that the shell recognises the
special case that allows the command in a sub-shell to output information
from the parent shell, rather than the sub-shell's information may not be
met.   The same applies to the "trap" command which has similar issues.

  | I guessed you have asked this because `jobs' would be specified as a
  | special built-in utility [XCU 2.14], which cannot be hidden by a
  | shell-function name, but it doesn't seem to be the case actually;

bash has very little belief in the concept of "special bui8lt-in".

  | POSIX also states that the results are unspecified when the command name
  | matches `builtin' according to [XCU 2.9.1 / Command Search and Execution /
  | rule 1b].

Yes, that's the same issue as with select [[ and more ... POSIX knows that
there are shells (like bash) which treat those differently than just being
normal commands, and so warns applications not to expect them to work as
normal commands.

There are no precise rules for when a shell should switch from parent shell
data to sub-shell data for commands like "trap" and "jobs" - the actual
expectation is very limited indeed, but shells can widen that, and allow
more cases through.   Eg: if one does

j=jobs

$j | wc -l

then it is not required that shells give special treatment to the jobs
command that is run, it might report only the sub-shell's jobs in that
case (ie: here, none).   That is, the shell can look at the text of the
command string when creating the sub-shell to decide what do do.   But
it is allowed to do more - the NetBSD sh here doesn't make decisions about
things like this until the command is about to be run, after all expansions,
even after function calls, so for us

mjjobs() { jobs "$@" ; }

myjobs | wc -l

will still count the number of lines in the jobs output from the parent
shell, as "jobs" is the first simple command run by the sub-shell, and that
is what counts (for us).   Other shells are likely to be more restricted.

Chet can decide if making bash handle more cases than it currently does is
worth it or not for bash and its users.

kre




Re: "builtin jobs" does not output to stdout.

2023-02-11 Thread Koichi Murase
2023年2月12日(日) 10:15 Robert Elz :

Thank you for the detailed explanations.  I totally agree with you on
all the points.

> Chet can decide if making bash handle more cases than it currently does is
> worth it or not for bash and its users.

Yes, Chet will decide.

--
Koichi