From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26045 invoked by alias); 19 Aug 2010 15:33:00 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 15298 Received: (qmail 14581 invoked from network); 19 Aug 2010 15:32:57 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received-SPF: none (ns1.primenet.com.au: domain at closedmail.com does not designate permitted sender hosts) From: Bart Schaefer Message-id: <100819083237.ZM26692@torch.brasslantern.com> Date: Thu, 19 Aug 2010 08:32:37 -0700 In-reply-to: <20100819124142.GQ16075@prunille.vinc17.org> Comments: In reply to Vincent Lefevre "process substitution and Ctrl-C" (Aug 19, 2:41pm) References: <20100819124142.GQ16075@prunille.vinc17.org> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-users@zsh.org Subject: Re: process substitution and Ctrl-C MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Aug 19, 2:41pm, Vincent Lefevre wrote: } } In the following example: } } { repeat 10 { date >&2; /bin/sleep 1 } } 2>>(cat -n; loop) } } where "loop" is a program that consumes CPU time, is it normal that } when one interrupts the command with Ctrl-C, the substituted process } isn't killed? (I can see "loop" taking CPU time.) The assumption is that process substitution consumes stdin and exits after its stdin is closed. Otherwise, why would you need to redirect into it? However, there may be a good reason for changing this. If I try echo >>(cat; sleep 100) then the shell is effectively frozen until "sleep 100" finishes, because "echo" is already gone and the process substitution is not interruptible, so nothing is paying attention to ^C or ^Z etc. This appears to happen with any builtin as the input to the process substitution, including a brace construct like the one you used above; e.g. I tried: { tty } >>(cat; sleep 100) and it hangs there for 100 seconds. However, it doesn't happen with an external command; e.g. tty >>(cat; sleep 100) exits immediately, even before the sleep finishes, though the sleep is left running. } The zsh man page says that the command is run asynchronously, but } this notion is never clearly defined. For better or worse, the zsh man page has never been very good about fully defining concepts that are "well known" from other shells. It was written from the standpoint of "you've already used (c)sh for a while and know what all of this means, I'm just going to tell you what is different about doing it in zsh." So if you refer to (say) the bash manual: A shell allows execution of GNU commands, both synchronously and asynchronously. The shell waits for synchronous commands to complete before accepting more input; asynchronous commands continue to execute in parallel with the shell while it reads and executes additional commands. Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation. When job control is not in effect, asynchronous commands ignore `SIGINT' and `SIGQUIT' in addition to these inherited handlers. Commands run as a result of command substitution ignore the keyboard-generated job control signals `SIGTTIN', `SIGTTOU', and `SIGTSTP'. What gets fuzzy, even in the bash manual, is the distinction between an "asynchronous command" and a "background job": If a command is terminated by the control operator `&', the shell executes the command asynchronously in a subshell. This is known as executing the command in the BACKGROUND. The shell does not wait for the command to finish, and the return status is 0 (true). When job control is not active, the standard input for asynchronous commands, in the absence of any explicit redirections, is redirected from `/dev/null'. Background processes are those whose process group ID differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a `SIGTTIN' (`SIGTTOU') signal by the terminal driver, which, unless caught, suspends the process. Zsh process substitution (and, I think, just about everything that zsh runs "asynchronously") behave in almost every way like background jobs, and therefore don't receive keyboard-generated signals.