[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