From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20393 invoked by alias); 6 Mar 2012 17:22:28 -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: 16848 Received: (qmail 28227 invoked from network); 6 Mar 2012 17:22:27 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS autolearn=ham version=3.3.2 Received-SPF: pass (ns1.primenet.com.au: SPF record at fifi.org designates 173.255.216.206 as permitted sender) Subject: Re: Is it possible to capture stdout and stderr to separate variables in Zsh? From: Philippe Troin To: Nikolai Weibull Cc: Zsh Users In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Date: Tue, 06 Mar 2012 09:16:25 -0800 Message-ID: <1331054185.27052.19.camel@air.fifi.org> Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 (2.30.3-1.fc13) Content-Transfer-Encoding: 8bit On Tue, 2012-03-06 at 09:09 +0100, Nikolai Weibull wrote: > Is it possible to capture stdout and stderr to separate variables in Zsh? > > I understand that it’s not possible in sh, but I was wondering if any > of Zsh’s additions in the redirection area would allow for such a > separation. All I can think of is: coproc cat & pid=$! stdout="$( ( print "printed on stdout"; print -u 2 "printer on stderr" ) 2>&p )" sleep 1 kill "$pid" stderr="$(cat <&p)" print "stdout=\"$stdout\"" print "stderr=\"$stderr\"" You'll notice the very ugly sleep+kill hack I had to use as I could not find how you can close a coprocess's standard input cleanly. Removing the sleep+kill makes the cat <&p hang forever. Of course this solution will hang if more than a buffer-full is printed on stderr. You can play tricks with dd by providing a bigger buffer, as in: coproc dd obs=1M & But in the end it's a losing game. You might as well use a temporary file for one of the output streams. A completely different solution could involve the tcp zsh module which can multiplex many streams with tcp_expect. But that's probably too involved for this problem. Phil.