bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: List of background processes in a command group, in a pipeline, exec


From: Stephane CHAZELAS
Subject: Re: List of background processes in a command group, in a pipeline, executed sequentially under certain conditions.
Date: Sun, 2 Oct 2011 21:49:55 +0100
User-agent: slrn/pre1.0.0-18 (Linux)

2011-10-01, 06:54(-05), Dan Douglas:
[...]
> f() {
>     local -i x y
>     while read -rN1 "x[y++]"; do
>         printf '%d ' "${1}" >&2    # keep track of which job this is.
>     done
>     printf "${#x[@]} "             # Print the total number of reads by each 
> job.

if you add a echo >&2 "[done $1]" here.
> }
>
> g() {                              # Used in ex 6
>     f 1 <${1} &
>     f 2 <${1}
> }
>
> # This works as I expect, f is backgrounded and two readers of one pipe each 
> get about half the input:
> exincr # 1
>
> read -ra x < <({ f 1 & f 2; } < <(zeros))
> printf '%b\n' "\n${x[@]}\n"
>
> # Equivalent to above, except with piped output. Now f is not backgrounded. 
> One reader consumes all the input:
> exincr # 2
>
> { f 1 & f 2; } < <(zeros) | {

You'll notice that f 1 terminates straight away. And if you do a
strace, you'll notice that bash does a dup2(open("/dev/null"),
0), that is redirecting "f 1"'s stdin to /dev/null.

~$ bash -c '{ cat; } < c | cat'
test
~$ bash -c '{ cat & } < c | cat'
~$ bash -c '{ lsof -ac lsof -d0; } < c | cat'
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
lsof    5005 chazelas    0r   REG  253,2        5 58785638 /home/chazelas/c
~$ bash -c '{ lsof -ac lsof -d0 & } < c | cat'
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
lsof    5010 chazelas    0r   CHR    1,3      0t0  973 /dev/null

That behavior is required by POSIX and occurs for ash and pdksh
and its derivatives as well:

POSIX> command1 & [command2 & ... ]
POSIX> 
POSIX>   The standard input for an asynchronous list, before any
POSIX>   explicit redirections are performed, shall be considered to
POSIX>   be assigned to a file that has the same properties as
POSIX>   /dev/null. If it is an interactive shell, this need not
POSIX>   happen. In all cases, explicit redirection of standard input
POSIX>   shall override this activity.

However, I don't know why bash does it only in the "pipe" case.

~$ ash -c '{ lsof -ac lsof -d0 & } < c'
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
lsof    5188 chazelas    0r   CHR    1,3      0t0  973 /dev/null
~$ bash -c '{ lsof -ac lsof -d0 & } < c'
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
lsof    5191 chazelas    0r   REG  253,2        5 58785638 /home/chazelas/c

To work around, this <&0 trick seems to work:

~$ bash -c '{ lsof -ac lsof -d0 <&0 & } < c | cat'
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
lsof    5247 chazelas    0r   REG  253,2        5 58785638 /home/chazelas/c

-- 
Stephane



reply via email to

[Prev in Thread] Current Thread [Next in Thread]