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=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, 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 bb371b8f for ; Sun, 24 Nov 2019 23:43:02 +0000 (UTC) Received: (qmail 15468 invoked by alias); 24 Nov 2019 23:42:44 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 44925 Received: (qmail 27319 invoked by uid 1010); 24 Nov 2019 23:42:44 -0000 X-Qmail-Scanner-Diagnostics: from injection.crustytoothpaste.net by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.0/25642. spamassassin: 3.4.2. Clear:RC:0(192.241.140.119):SA:0(-1.9/5.0):. Processed in 2.65794 secs); 24 Nov 2019 23:42:44 -0000 X-Envelope-From: sandals@crustytoothpaste.net X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at crustytoothpaste.net designates 192.241.140.119 as permitted sender) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=crustytoothpaste.net; s=default; t=1574638928; bh=mjeZni6KHAOppcumush3XHXUTQ4+7Zc4gQ86HnVXGYE=; h=From:To:Subject:Date:In-Reply-To:References:From:Reply-To:Subject: Date:To:CC:Resent-Date:Resent-From:Resent-To:Resent-Cc:In-Reply-To: References:Content-Type:Content-Disposition; b=M8LIsWp/Elwjt54wFkb2HsU4yL6IIq2b75cLRfnk+flj08Bg9VFJFV57ccjNATN1M s0+VlGmmvYZFrU9ayzGKvrizStuqbR/uPh7I2bzQbas+hjj34LN8YS+iye3dopYNj+ VALIomRp10TAFlWu7awjT1eWeJidxw3zz+GpcqP820HK6PK4YqCbpOqffQBkJva12J Hmk+A0ZKGO+tRFWZAsxqzl2ogQ5KbW2iEhqAS7+90w2/KpEjHF3k9F+zGfUV6HmNr3 NIQU4fqQtsL8eGh/N0NHbrnUGjr6Ak8VtAAu44GYmNAJSZrClxmm0pvYk8Hh232hxQ 35TPvz46P8TedAfHlgM1tBycov4RcVD8qIt3/bJGKHzXaRAz5WSANxWK42jq0RcTDs a4rbaudiydBd9tcS3gVJqYGvDb1+EBo0zis4IzITNLZNedQzAA95fxtV2s/dvpcUVa rXIR7biuhP+4QzFB9nCXf9qkjU3akZQ3Sb/E0rKuE2sSxSVNxZd From: "brian m. carlson" To: zsh-workers@zsh.org Subject: [PATCH 1/1] exec: run final pipeline command in a subshell in sh mode Date: Sun, 24 Nov 2019 23:41:19 +0000 Message-Id: <20191124234119.2403456-2-sandals@crustytoothpaste.net> X-Mailer: git-send-email 2.24.0.359.ga6e4e5af0a In-Reply-To: <20191124234119.2403456-1-sandals@crustytoothpaste.net> References: <20191124234119.2403456-1-sandals@crustytoothpaste.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Qmail-Scanner-2.11: added fake Content-Type header Content-Type: text/plain zsh typically runs the final command in a pipeline in the main shell instead of a subshell. However, POSIX requires that all commands in a pipeline run in a subshell, but permits zsh's behavior as an extension. Since zsh may be used as /bin/sh in some cases (such as macOS Catalina), it makes sense to have the POSIX behavior when emulating sh, so do that by checking for being the final item of a multi-item pipeline and creating a subshell in that case. --- Src/exec.c | 10 ++++++---- Test/B07emulate.ztst | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index 6014ec9a5..66dc8db2d 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2861,11 +2861,13 @@ execcmd_exec(Estate state, Execcmd_params eparams, pushnode(args, dupstring("fg")); } - if ((how & Z_ASYNC) || output) { + if ((how & Z_ASYNC) || output || + (last1 == 2 && input && EMULATION(EMULATE_SH))) { /* - * If running in the background, or not the last command in a - * pipeline, we don't need any of the rest of this function to - * affect the state in the main shell, so fork immediately. + * If running in the background, not the last command in a + * pipeline, or the last command in a multi-stage pipeline + * in sh mode, we don't need any of the rest of this function + * to affect the state in the main shell, so fork immediately. * * In other cases we may need to process the command line * a bit further before we make the decision. diff --git a/Test/B07emulate.ztst b/Test/B07emulate.ztst index 7b1592fa9..45c39b51d 100644 --- a/Test/B07emulate.ztst +++ b/Test/B07emulate.ztst @@ -276,3 +276,25 @@ F:Some reserved tokens are handled in alias expansion 0:--emulate followed by other options >yes >no + + emulate sh -c ' + foo () { + VAR=foo && + echo $VAR | bar && + echo "$VAR" + } + bar () { + tr f b && + VAR="$(echo bar | tr r z)" && + echo "$VAR" + } + foo + ' + emulate sh -c 'func() { echo | local def="abc"; echo $def;}; func' + emulate sh -c 'abc="def"; echo | abc="ghi"; echo $abc' +0:emulate sh uses subshell for last pipe entry +>boo +>baz +>foo +> +>def