From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19203 invoked by alias); 4 Nov 2014 07:13:17 -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: 19330 Received: (qmail 5802 invoked from network); 4 Nov 2014 07:13:14 -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,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=Ao9ZB15K c=1 sm=1 tr=0 a=FT8er97JFeGWzr5TCOCO5w==:117 a=kj9zAlcOel0A:10 a=q2GGsy2AAAAA:8 a=oR5dmqMzAAAA:8 a=-9mUelKeXuEA:10 a=CQVvdnapVFz3F5vI2_IA:9 a=CjuIK1q_8ugA:10 From: Bart Schaefer Message-id: <141103231312.ZM32403@torch.brasslantern.com> Date: Mon, 03 Nov 2014 23:13:12 -0800 In-reply-to: <5458743B.2000204@eastlink.ca> Comments: In reply to Ray Andrews "Re: for loop question" (Nov 3, 10:37pm) References: <5456984A.3020001@eastlink.ca> <20141102213713.GA4412@chaz.gmail.com> <20141104015639.GA2871@localhost.localdomain> <141103184338.ZM32221@torch.brasslantern.com> <5458743B.2000204@eastlink.ca> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-users@zsh.org Subject: Re: for loop question MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Nov 3, 10:37pm, Ray Andrews wrote: } Subject: Re: for loop question } } On 11/03/2014 06:43 PM, Bart Schaefer wrote: } > The 0 is appended because [ -n "$TLC[i]" ] does not produce any output, } But in } } if [ -n "$TLC[i]" ] } } ... the test must surely produce an answer of some sort. The *nix command paradigm is organized around two concepts: (1) passing data through file streams, of which stdin and stdout are the basis for connecting commands as pipelines; and (2) the input argument array and integer exit status mapped straight onto C's main() function, with zero for success and any nonzero value for failure. The idea is that there are many ways to fail (among which you might want to distinguish) but only one way to succeed, and zero is a conviently unique value. Shells are designed for linking together other programs (some of which are built in to the shell) using these two paradigms. Conditions like "if" and "while" test the exit status; pipelines and substitutions use the data streams. If the exit status and the data stream were mixed together, you could never pass pure data through a pipeline, and you could never test for program failure without sticking your fingers in its data stream. $? [and $status in csh and zsh] exists for the purpose of transforming an exit status back into an argument list; "echo" [and "print"] is for transforming argument lists into stream data; "test" transforms an argument list into an exit status; "read" [and $(...) which originally was `...`] converts a stream to an argument list. Plug these four things together in the right ways and you can build any program linkage you need. This is the basic elegance of the shell. Math operations and all the various parameter manipulations were bolted onto the top of this model for efficiency, adding complexity for speed at the cost of elegance. Originally one had to call programs like "expr" and "basename" to do all that work, and read back the results from the their stdout streams. (More ways to transform argument lists into stream data.) But that required forking processes and setting up data pipes and was slow and expensive, so ... } Yes or no. If that answer is not acceptable as 'arithmetic', then what } is it? It's an exit status, which is a thing separate from the data model. If you want it as data (argument list or stream), you have to convert it. If "test" produced both an exit status and an output stream, you'd have to be constantly throwing away one or the other, so it only produces the exit status because that's what you want most often, and you use $? if you need that in another form. Shell math works on argument lists (which happen to be interpreted as variable names and numbers), not on exit status values. (( )) is just syntactic sugar for converting numbers to exit status, and $(( )) is sugar for converting from numbers back to arguments. I won't quote the rest of your questions, because I think the above has answered them. If you REALLY want to understand why shells are the way they are, you need to study the history of C and UNIX.