From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6243 invoked by alias); 3 Nov 2015 08:48:33 -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: 20891 Received: (qmail 4320 invoked from network); 3 Nov 2015 08:48:32 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:mail-followup-to:references :mime-version:content-type:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=x+l93vZ4diWTDKOiu6jqX7yCXLzVcirMwP1NPEmk3Ls=; b=mlFqoxBb8rJGeuLPosHvBKVQ8kcO2tRdzFv8SHX7lekCiYb79oWmBQZVtbjaIR627Z W49qGeZP18AwcXveO0lkC+VUQRGQqxqywcIuRQD5Obo/tN5jh9onsw1W/VRExWuvJw7J 9OPrn0q+koKw8m/JYzaxadPrkIj2fPXr1HWyaktAqK5n1RuFTjEJB/aOBFJGS9j/6MKR Y6VkgBhImHRHP8rNaVtMSfBrJp/7DftekVGPhKKHjzN0eCXnSbftkcl5trFXaf2I4S0+ y3svrFQqiarDLkAhSMECPX5WM5aNIvvsRjC+iLsx9w8HvD5HGXrt+cOQODgdefrMYLPS Tr0Q== X-Received: by 10.28.13.75 with SMTP id 72mr17279492wmn.20.1446540509072; Tue, 03 Nov 2015 00:48:29 -0800 (PST) Date: Tue, 3 Nov 2015 08:47:57 +0000 From: Stephane Chazelas To: Alexander Skwar Cc: zsh-users@zsh.org Subject: Re: for loop with parameter expansion in zsh vs. bash Message-ID: <20151103084757.GB6580@chaz.gmail.com> Mail-Followup-To: Alexander Skwar , zsh-users@zsh.org References: <20151103073547.GA6580@chaz.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) 2015-11-03 08:47:42 +0100, Alexander Skwar: [...] > > IFS=: > > for e in $~PATH Sorry, meant $=PATH above ($= looks like scissors) > > Or use the "s" expansion flag: > > > > for e in "${(s(:))PATH}" Note that those don't work if $PATH is empty (which for command search means one empty element) or unset (which for command search means commands are looked in a default $PATH (whose value depends on the shell)). > ​Great. Thanks. Appreciated. > > > Too bad, that there's such a difference between the shells. Makes it hard > to share snippets with co-workers, who (for reasons, that I fail to > understand) don't use zsh. > > Because of that, I'm actually using something along the lines of: > > for e in $(echo "$PATH" | tr ':' ' '); do echo e $e; done > > This works everywhere.​ Note that it is slightly more correct in zsh (that performs only split upon command substitution) than in other shells that perform split+glob. The use of echo causes problems with things that start with - or contain backslashes though. The use of command substitution means that trailing newlines in the last element are trimmed. set -o noglob; IFS=:; for e in $(printf %s "$PATH") would be better (still a problem for trailing newlines). Note that if you want to have zsh interpret sh code, you can use "emulate -L zsh". The -L makes that "emulation" local to the current function context. So to share code between zsh and POSIX compliant shells, you could do: if [ "$ZSH_VERSION" ]; then alias 'START_SH_CODE=function { emulate -L sh' alias 'END_SH_CODE=} "$@"' else START_SH_CODE() { :; } END_SH_CODE() { :; } fi And use as: START_SH_CODE IFS=: set -f for e in $PATH; do ...; done END_SH_CODE (note that it has the side effect of creating a function context (the code is parsed as a whole, the positional parameters and variables you declare inside are local to that block, "return" breaks only out of that block. (note that doing the same for bash (which by default, unless in sh emulation is not POSIX compliant either though the differences are a lot smaller) is a lot trickier as bash doesn't have local scope for options or anonymous functions like zsh). -- Stephane