From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from primenet.com.au (ns1.primenet.com.au [203.24.36.2]) by inbox.vuxu.org (OpenSMTPD) with ESMTP id ffe51ef9 for ; Sat, 29 Jun 2019 16:18:10 +0000 (UTC) Received: (qmail 111 invoked by alias); 29 Jun 2019 16:18:03 -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: List-Unsubscribe: X-Seq: 23996 Received: (qmail 856 invoked by uid 1010); 29 Jun 2019 16:18:03 -0000 X-Qmail-Scanner-Diagnostics: from mail-lf1-f51.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.101.2/25489. spamassassin: 3.4.2. Clear:RC:0(209.85.167.51):SA:0(-1.9/5.0):. Processed in 2.499116 secs); 29 Jun 2019 16:18:03 -0000 X-Envelope-From: schaefer@brasslantern.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _netblocks.google.com designates 209.85.167.51 as permitted sender) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=Gs9ScdnjHMlFqbmZWaa03Oc8MdHD+N+Cr4YSvpTBR60=; b=DJexoCpF0so6c+PgcehUR6gjCl0xQg4k9Xi292t+xV4eKVOZH/2CPHXkc8Y6UI+Toz VWNpENujh8wTjlrSdrOa6Wl+8RC/b88MAMSelOMMbWvk04+5Iun+hnrnVbCmdN1G+dOo bJ0llHjkt1/bAEbjrUE4jIRqzJGh9GuOirL1VgjonmJ5s1tuiT7c9FPnwPG2ZpyYX/in W9aVVP5F94cn65PeeEgUaomUDnhBQlO+8NDvj1ewuXy7fGUtfhwvRZePNwLWMBwdItw0 x6Or0+PQS1vIJhO9X3NqARoMgBLDflxr9Fms6dAeoOAipvBCSdao2doY9IDXo5VmZt4a Uf7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=Gs9ScdnjHMlFqbmZWaa03Oc8MdHD+N+Cr4YSvpTBR60=; b=uidSLBpzCUs3XcSuvsX4uzk2LBWuXuviYoKVmbNt0Gk7lfNsPotg9P13LUubWQ+4YI MizwzTAUKt+ngHPLMZmT0kJGVXbKpVpWm5kjcwHBy10UiXsjx0PlDDHq0pDBg6tlD1ai 3WqYrPR8Jy8U4twIHUr836iC62ocwUv/ctdJCJGSxeI5DunA54VYeSD5dOGSOjkGS9YZ hkgyHh+uBIqAtdjVRh0jQkxnDX2LCsFO5DzEq5UbMuxUxb3cd46xq5i+2H2tYKVwsmjE fex87DOoCHK8+9U2mTufdXjfwPwO32UyqfRr1ljZe96OVEO4udt+C91bVS5h9xHryuKm PEAA== X-Gm-Message-State: APjAAAXWkLVmES3mqQox3I63DSY6I8ZrXXyz9iUHMMNy1kJbOfxaFwRr Xja5OX1vMZ4Vbr9ZL/GopjO0qLAJtWae4dzX4z5u1iIjvsxu7g== X-Google-Smtp-Source: APXvYqzQ+7czSvbdBjFXVnEih/mc1X9cfcJKonkbyxg0S8C/NZN4jjDI+HPvzGpS96j6j53Z5qbKpTqN8MVFYbUBIes= X-Received: by 2002:ac2:43bb:: with SMTP id t27mr7810642lfl.187.1561825045271; Sat, 29 Jun 2019 09:17:25 -0700 (PDT) MIME-Version: 1.0 References: <20190628110430.GA13790@zira.vinc17.org> In-Reply-To: <20190628110430.GA13790@zira.vinc17.org> From: Bart Schaefer Date: Sat, 29 Jun 2019 09:17:13 -0700 Message-ID: Subject: Re: kill the LHS command of a pipe once the RHS command terminates To: Zsh Users Content-Type: text/plain; charset="UTF-8" On Fri, Jun 28, 2019 at 4:05 AM Vincent Lefevre wrote: > > With some commands I pipe the output to a pager, and when quitting > the pager, I want the command to terminate immediately (so that it > doesn't consume more resources) and want the shell prompt back. This is going to happen in cases where the left-side command doesn't produce enough output to fill the OS buffer used for the pipe, so it doesn't see the end-of-file or receive the PIPE signal when the right-side command closes the other end. In your examples, you've also got compound structures that are actually ignoring the state of their standard output once the small amount of initial output has been sent. Neither the shell nor the OS has any way of "knowing" that you didn't INTEND those commands to continue running. > Does zsh provide a feature to kill the left-hand-side command in a > clean way (without a race condition, without a temporary file...)? That's supposed to be the EOF+SIGPIPE, but it only works for "well behaved" commands that are actually doing something useful with their standard output. In addition to Stephane's suggestions, you can also get control of your left-side by using "coproc". This creates an actual job table entry that you can manipulate. zsh% coproc { echo foo; sleep 3; echo err >&2 }; head -n 1 <&p; kill %+ [1] 53747 foo zsh% [1] + terminated { echo foo; sleep 3; echo err >&2; } zsh% If you're going to kill the right-side with an interrupt or other signal, you'll have to arrange to trap that so that the subsequent kill isn't also skipped. Also in practice you want something more specific than "kill %+" which could kill the wrong job if you have multiple backgrounded jobs and the coproc exits before the kill occurs.