* for loop question @ 2014-11-02 20:47 Ray Andrews 2014-11-02 21:00 ` Bart Schaefer [not found] ` <CAH+w=7aWS0xyS4CXRJBphDjesfUFQOsyJRMaG3RZRxmuj7xkOg__20885.3257158355$1414962125$gmane$org@mail.gmail.com> 0 siblings, 2 replies; 19+ messages in thread From: Ray Andrews @ 2014-11-02 20:47 UTC (permalink / raw) To: Zsh Users test() { # THIS WORKS FINE: i=1 while [ -n "$TLC[i]" ]; do let i=i+1 print -ru2 $TLC[i] done # THIS WORKS FINE: for ((i=1; i<6; i++)) do print -ru2 $TLC[i] done # ... BUT THIS FAILS WITH "BAD OUTPUT FORMAT SPECIFICATION": for ((i=1; [ -n "$TLC[i]" ]; i++)) do print -ru2 $TLC[i] done } I've fiddled around with various modifications but it seems to dislike " [ -n "$TLC[i]" ] " even though the 'while' loop is happy with it. That expression evaluates to true or false, does it not? So why won't 'for' swallow it? ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 20:47 for loop question Ray Andrews @ 2014-11-02 21:00 ` Bart Schaefer [not found] ` <CAH+w=7aWS0xyS4CXRJBphDjesfUFQOsyJRMaG3RZRxmuj7xkOg__20885.3257158355$1414962125$gmane$org@mail.gmail.com> 1 sibling, 0 replies; 19+ messages in thread From: Bart Schaefer @ 2014-11-02 21:00 UTC (permalink / raw) To: Ray Andrews; +Cc: Zsh Users [-- Attachment #1: Type: text/plain, Size: 396 bytes --] > I've fiddled around with various modifications but it seems to dislike " [ -n "$TLC[i]" ] " > even though the 'while' loop is happy with it. That expression evaluates to true or > false, does it not? So why won't 'for' swallow it? The double parents (( )) are special arithmetic syntax. You can't use an ordinary shell command like "test" ( for which "[" is an alias) inside that construct. ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <CAH+w=7aWS0xyS4CXRJBphDjesfUFQOsyJRMaG3RZRxmuj7xkOg__20885.3257158355$1414962125$gmane$org@mail.gmail.com>]
* Re: for loop question [not found] ` <CAH+w=7aWS0xyS4CXRJBphDjesfUFQOsyJRMaG3RZRxmuj7xkOg__20885.3257158355$1414962125$gmane$org@mail.gmail.com> @ 2014-11-02 21:37 ` Stephane Chazelas 2014-11-02 22:44 ` Ray Andrews ` (2 more replies) 0 siblings, 3 replies; 19+ messages in thread From: Stephane Chazelas @ 2014-11-02 21:37 UTC (permalink / raw) To: Bart Schaefer; +Cc: Ray Andrews, Zsh Users 2014-11-02 13:00:14 -0800, Bart Schaefer: > > I've fiddled around with various modifications but it seems to dislike " > [ -n "$TLC[i]" ] " > > even though the 'while' loop is happy with it. That expression evaluates > to true or > > false, does it not? So why won't 'for' swallow it? > > The double parents (( )) are special arithmetic syntax. You can't use an > ordinary shell command like "test" ( for which "[" is an alias) inside that > construct. You could with: for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) print -ru2 -- $TLC[i] (not that you would want to). Here, you more likely want: for i ("$TLC[@]") print -ru2 -- $i or print -rlu2 -- "$TLC[@]" or: for ((i = 1; i <= $#TLC; i++)) print -ru2 -- $TLC[i] Or (to print only till the first empty element): for ((i = 1; $#TLC[i]; i++)) print -ru2 -- "$TLC[i]" Or: print -rlu2 -- "${(@)TLC[1,TLC[(i)]-1]}" -- Stephane ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 21:37 ` Stephane Chazelas @ 2014-11-02 22:44 ` Ray Andrews 2014-11-02 22:57 ` Bart Schaefer 2014-11-02 23:24 ` Oliver Kiddle 2014-11-03 1:53 ` Mikael Magnusson 2014-11-04 1:56 ` Han Pingtian 2 siblings, 2 replies; 19+ messages in thread From: Ray Andrews @ 2014-11-02 22:44 UTC (permalink / raw) To: zsh-users On 11/02/2014 01:37 PM, Stephane Chazelas wrote: > You could with: > > for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) > print -ru2 -- $TLC[i] > > (not that you would want to). No. That is pure sadism ;-) ;-) But it does show that 'for ((' CAN stop and digest ' [ -n "$TLC[i]" ] ' if it wants too, it just has to make it obscenely difficult. Why can't the truth test of a command just be taken as 'arithmetic' plain and simple? $ for ((; 1 ;)) echo true! true! true! true! ..... $ for ((; 0 ;)) echo true! [nothing] .... so why/how is it that the return value of a ' [] ' test is NOT either 1 or 0? Thanks for these, there is much to learn from them: > Here, you more likely want: > > for i ("$TLC[@]") print -ru2 -- $i > > or > > print -rlu2 -- "$TLC[@]" > > or: > > for ((i = 1; i <= $#TLC; i++)) print -ru2 -- $TLC[i] > > > Or (to print only till the first empty element): > > for ((i = 1; $#TLC[i]; i++)) print -ru2 -- "$TLC[i]" > > Or: > > print -rlu2 -- "${(@)TLC[1,TLC[(i)]-1]}" > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 22:44 ` Ray Andrews @ 2014-11-02 22:57 ` Bart Schaefer 2014-11-02 23:24 ` Oliver Kiddle 1 sibling, 0 replies; 19+ messages in thread From: Bart Schaefer @ 2014-11-02 22:57 UTC (permalink / raw) To: Zsh Users [-- Attachment #1: Type: text/plain, Size: 716 bytes --] On Nov 2, 2014 2:42 PM, "Ray Andrews" <rayandrews@eastlink.ca> wrote: > > But it does show that 'for ((' CAN stop and digest ' [ -n "$TLC[i]" ] ' if it wants too, > it just has to make it obscenely difficult. Why can't the truth test of a command just be taken > as 'arithmetic' plain and simple? It's a matter of order-of-evaluation and contextual tokenization. Once the parser encounters "for ((" it stops looking for ordinary shell command tokens and starts looking for math tokens; a word like "test" in that context is a numeric variable name, not a command name, and "[" has another meaning as well. But "$" introduces an expansion in either context, so $(...) switches back into the regular parsing mode. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 22:44 ` Ray Andrews 2014-11-02 22:57 ` Bart Schaefer @ 2014-11-02 23:24 ` Oliver Kiddle 2014-11-03 0:07 ` Ray Andrews 1 sibling, 1 reply; 19+ messages in thread From: Oliver Kiddle @ 2014-11-02 23:24 UTC (permalink / raw) To: Ray Andrews; +Cc: zsh-users Ray Andrews wrote: > > You could with: > > > > for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) > > print -ru2 -- $TLC[i] > > > > (not that you would want to). > No. That is pure sadism ;-) ;-) > > But it does show that 'for ((' CAN stop and digest ' [ -n "$TLC[i]" ] > ' if it wants too, > it just has to make it obscenely difficult. Why can't the truth test of > a command just be taken > as 'arithmetic' plain and simple? Inside of (( ... )) is arithmetic context. So different syntax is valid there. [ is just a command. Look at the error message you get if you put it there: % for ((; [ -f foo ] ; )) echo true zsh: bad output format specification Zsh sees the square brackets and in arithmetic context, square brackets are used for selecting an output format, specifically a number base. For example: % echo $(( [#2] 37 )) 2#100101 There's also a command named true which just returns true. So what do you think the following might do: % for ((; true ;)) echo true! This actually looks for the variable $true and interprets it as a number. As you can see, the syntaxes conflict. While we could add a simple way to escape back into normal syntax from arithmetic syntax, it'd be no nicer than the existing alternatives. Oliver ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 23:24 ` Oliver Kiddle @ 2014-11-03 0:07 ` Ray Andrews 0 siblings, 0 replies; 19+ messages in thread From: Ray Andrews @ 2014-11-03 0:07 UTC (permalink / raw) To: Oliver Kiddle; +Cc: zsh-users On 11/02/2014 03:24 PM, Oliver Kiddle wrote: > As you can see, the syntaxes conflict. While we could add a simple way > to escape back into normal syntax from arithmetic syntax, it'd be no > nicer than the existing alternatives. > Oliver This is going to take so long to get comfortable with . Anyway, you can't break the grammar. It might look like it could be simple, but if it's a violation, then it's a violation. For now I'll take it on faith that this: (z[$([ -n "$TLC[i]" ])0]),$? == 0; is as simple as it can be. Practically speaking, tho, those other examples are very nice, so this is just theoretical whining. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 21:37 ` Stephane Chazelas 2014-11-02 22:44 ` Ray Andrews @ 2014-11-03 1:53 ` Mikael Magnusson 2014-11-03 2:22 ` Ray Andrews 2014-11-04 1:56 ` Han Pingtian 2 siblings, 1 reply; 19+ messages in thread From: Mikael Magnusson @ 2014-11-03 1:53 UTC (permalink / raw) To: Bart Schaefer, Ray Andrews, Zsh Users On Sun, Nov 2, 2014 at 10:37 PM, Stephane Chazelas <stephane.chazelas@gmail.com> wrote: > 2014-11-02 13:00:14 -0800, Bart Schaefer: >> > I've fiddled around with various modifications but it seems to dislike " >> [ -n "$TLC[i]" ] " >> > even though the 'while' loop is happy with it. That expression evaluates >> to true or >> > false, does it not? So why won't 'for' swallow it? >> >> The double parents (( )) are special arithmetic syntax. You can't use an >> ordinary shell command like "test" ( for which "[" is an alias) inside that >> construct. > > You could with: > > for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) > print -ru2 -- $TLC[i] > > (not that you would want to). > > Here, you more likely want: > > for i ("$TLC[@]") print -ru2 -- $i > > or > > print -rlu2 -- "$TLC[@]" > > or: > > for ((i = 1; i <= $#TLC; i++)) print -ru2 -- $TLC[i] > > > Or (to print only till the first empty element): > > for ((i = 1; $#TLC[i]; i++)) print -ru2 -- "$TLC[i]" > > Or: > > print -rlu2 -- "${(@)TLC[1,TLC[(i)]-1]}" We might want to avoid using obscure mixes of the discouraged alternate syntax with syntax that depends on short_loops being set, when helping people who are asking questions about basic syntax. :) -- Mikael Magnusson ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-03 1:53 ` Mikael Magnusson @ 2014-11-03 2:22 ` Ray Andrews 2014-11-03 9:22 ` Mikael Magnusson 0 siblings, 1 reply; 19+ messages in thread From: Ray Andrews @ 2014-11-03 2:22 UTC (permalink / raw) To: Mikael Magnusson, Bart Schaefer, Zsh Users On 11/02/2014 05:53 PM, Mikael Magnusson wrote: > We might want to avoid using obscure mixes of the discouraged > alternate syntax with syntax that depends on short_loops being set, > when helping people who are asking questions about basic syntax. :) It does get a bit overwhelming. However, when I poke at the syntax by asking 'why can't we ...' sorts of questions, I expect to more or less have my fuses blown ;-) Still, any sort of heads up about what is considered proper vs. what is considered discouraged will be most appropriate. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-03 2:22 ` Ray Andrews @ 2014-11-03 9:22 ` Mikael Magnusson 2014-11-03 17:26 ` Ray Andrews 0 siblings, 1 reply; 19+ messages in thread From: Mikael Magnusson @ 2014-11-03 9:22 UTC (permalink / raw) To: Ray Andrews; +Cc: Zsh Users On Mon, Nov 3, 2014 at 3:22 AM, Ray Andrews <rayandrews@eastlink.ca> wrote: > On 11/02/2014 05:53 PM, Mikael Magnusson wrote: >> >> We might want to avoid using obscure mixes of the discouraged alternate >> syntax with syntax that depends on short_loops being set, when helping >> people who are asking questions about basic syntax. :) > > It does get a bit overwhelming. However, when I poke at the syntax by > asking 'why can't we ...' sorts of questions, I expect to more or less have > my fuses blown ;-) Still, any sort of heads up about what is considered > proper vs. what is considered discouraged will be most appropriate. If you look up the section "Complex Commands" in the manpage, they're all listed fairly well explained. The section after that is called "Alternate Forms for Complex Commands" and lists some syntax that is convenient interactively but not super encouraged. Using any syntax that depends on SHORT_LOOPS being set will of course not work in any other shell, and also has the downside that making a small mistake will usually still parse but do something entirely unexpected. I'm a bit more opposed to SHORT_LOOPS than others here, but when I disabled the option, I immediately found like 5 bugs in the completion system so I think I'm at least somewhat justified :). The whole point of it is just to not have to write do; done, but it causes so many bugs and confusion. As to the for loop, it has two different forms. They're almost so different you could say the only thing they have in common is the word "for" :). One is for some variables in list of values; do list; of; commands using $some $variables done Think of that as a foreach loop. The other form is for (( i=0; i<10; i++ )); do list; of; commands using $i done This form is exclusively for math expressions, you can't just stick arbitrary commands in there. If you want that, just use a while loop. commands to initialize state while my condition; do stuff here increment iterator or whatever done because as you saw, stuffing it all into the for line would just get really ugly. And you want the foreach form for your initial example as Stephane said, there is no need to iterate over the index unless you have a veeery large array, and then it will already be very slow anyway. As a side note, if you ever want a do-while loop instead of a regular while loop, the trick is while just put the whole body; of the loop here instead; and the last command is; the terminating condition; do done -- Mikael Magnusson ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-03 9:22 ` Mikael Magnusson @ 2014-11-03 17:26 ` Ray Andrews 0 siblings, 0 replies; 19+ messages in thread From: Ray Andrews @ 2014-11-03 17:26 UTC (permalink / raw) To: Mikael Magnusson; +Cc: Zsh Users On 11/03/2014 01:22 AM, Mikael Magnusson wrote: > If you look up the section "Complex Commands" in the manpage, they're > all listed fairly well explained. ... Thanks. You know, with so many documents available, it's hard to know what it worth reading. I wish there was a sort of recommended list of docs and web sites so that one wouldn't waste so much time looking for things worth reading. I have Oliver's book here, and at least I know it's approved. > As to the for loop, it has two different forms. They're almost so > different you could say the only thing they have in common is the word > "for" :). One is Just those three lines might save a fella hours of grief. I intuitively expect them to be related *and* to be related to the C form, which explains my head banging over: for ((i = 1; [ -n ${TLC[i] ]; i++)) ... because in C one can always test for the return value of anything at all and it looks so very much like C. for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) ... is sick and twisted, but: for ((i = 1; $#TLC[i]; i++)) ... is sweetly, intuitively best anyway. > As a side note, if you ever want a do-while loop instead of a regular > while loop, the trick is > while just put the whole body; > of the loop here instead; > and the last command is; > the terminating condition; do done Marvelous, I was wondering about that. If I ever master zsh I'd like to write an essay: "Zsh culture for the sweet and innocent: Truths you hold to be self-evident that aren't true any more, or the weltanschauung of weltschmertz" ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-02 21:37 ` Stephane Chazelas 2014-11-02 22:44 ` Ray Andrews 2014-11-03 1:53 ` Mikael Magnusson @ 2014-11-04 1:56 ` Han Pingtian 2014-11-04 2:29 ` Han Pingtian ` (2 more replies) 2 siblings, 3 replies; 19+ messages in thread From: Han Pingtian @ 2014-11-04 1:56 UTC (permalink / raw) To: zsh-users; +Cc: Bart Schaefer, Ray Andrews On Sun, Nov 02, 2014 at 09:37:13PM +0000, Stephane Chazelas wrote: > 2014-11-02 13:00:14 -0800, Bart Schaefer: > > > I've fiddled around with various modifications but it seems to dislike " > > [ -n "$TLC[i]" ] " > > > even though the 'while' loop is happy with it. That expression evaluates > > to true or > > > false, does it not? So why won't 'for' swallow it? > > > > The double parents (( )) are special arithmetic syntax. You can't use an > > ordinary shell command like "test" ( for which "[" is an alias) inside that > > construct. > > You could with: > > for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) > print -ru2 -- $TLC[i] > What does the (z[$([ -n "$TLC[i]" ])0]) mean, please? ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-04 1:56 ` Han Pingtian @ 2014-11-04 2:29 ` Han Pingtian 2014-11-04 2:43 ` Bart Schaefer [not found] ` <141103184338.ZM32221__48957.5251042426$1415069142$gmane$org@torch.brasslantern.com> 2 siblings, 0 replies; 19+ messages in thread From: Han Pingtian @ 2014-11-04 2:29 UTC (permalink / raw) To: zsh-users; +Cc: Bart Schaefer, Ray Andrews On Tue, Nov 04, 2014 at 09:56:39AM +0800, Han Pingtian wrote: > On Sun, Nov 02, 2014 at 09:37:13PM +0000, Stephane Chazelas wrote: > > 2014-11-02 13:00:14 -0800, Bart Schaefer: > > > > I've fiddled around with various modifications but it seems to dislike " > > > [ -n "$TLC[i]" ] " > > > > even though the 'while' loop is happy with it. That expression evaluates > > > to true or > > > > false, does it not? So why won't 'for' swallow it? > > > > > > The double parents (( )) are special arithmetic syntax. You can't use an > > > ordinary shell command like "test" ( for which "[" is an alias) inside that > > > construct. > > > > You could with: > > > > for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) > > print -ru2 -- $TLC[i] > > > What does the (z[$([ -n "$TLC[i]" ])0]) mean, please? > I think I have got the meaning of it. The goal is to run '[ -n "$TLC[i]" ]' in a math context, so embed the testing in the subscript of 'z[..]'. The 'z' will be explained as a array in this math context, the value of '$z[...]' is ignored, only the result of '[ -n "$TLC[i]" ]' is compared with 0. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-04 1:56 ` Han Pingtian 2014-11-04 2:29 ` Han Pingtian @ 2014-11-04 2:43 ` Bart Schaefer 2014-11-04 4:51 ` Han Pingtian 2014-11-04 6:37 ` Ray Andrews [not found] ` <141103184338.ZM32221__48957.5251042426$1415069142$gmane$org@torch.brasslantern.com> 2 siblings, 2 replies; 19+ messages in thread From: Bart Schaefer @ 2014-11-04 2:43 UTC (permalink / raw) To: zsh-users On Nov 4, 9:56am, Han Pingtian wrote: } } > for ((i=1; (z[$([ -n "$TLC[i]" ])0]),$? == 0; i++)) } > print -ru2 -- $TLC[i] } > } What does the (z[$([ -n "$TLC[i]" ])0]) mean, please? It's an overly-obfuscated way to write $([ -n "$TLC[i]" ]). The real work is the ",$?" part. z[...],$? is used to throw away the z[...] part and keep the value of $?. The value of $? comes from the side-effect of the $(...) inside the subscript of z[...]. The 0 is appended because [ -n "$TLC[i]" ] does not produce any output, but there has to be a valid number as the subscript, hence z[0]. This could be written a LOT more plainly as for ((i=1; $([ -n "$TLC[i]" ]; echo $?) == 0; i++)) without needing any more characters. If we're playing golf, for ((i=1; ! $([ "$TLC[i]" ]; echo $?); i++)) works too. Which, by the way, points out another reason you can't just use the exit status of a command in a math context: command success/failure are the reverse of true/false when taken as integer values. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-04 2:43 ` Bart Schaefer @ 2014-11-04 4:51 ` Han Pingtian 2014-11-04 6:37 ` Ray Andrews 1 sibling, 0 replies; 19+ messages in thread From: Han Pingtian @ 2014-11-04 4:51 UTC (permalink / raw) To: zsh-users On Mon, Nov 03, 2014 at 06:43:38PM -0800, Bart Schaefer wrote: > } What does the (z[$([ -n "$TLC[i]" ])0]) mean, please? > > It's an overly-obfuscated way to write $([ -n "$TLC[i]" ]). The real > work is the ",$?" part. > > z[...],$? is used to throw away the z[...] part and keep the value of $?. > > The value of $? comes from the side-effect of the $(...) inside the > subscript of z[...]. > > The 0 is appended because [ -n "$TLC[i]" ] does not produce any output, > but there has to be a valid number as the subscript, hence z[0]. > > This could be written a LOT more plainly as > > for ((i=1; $([ -n "$TLC[i]" ]; echo $?) == 0; i++)) > > without needing any more characters. If we're playing golf, > > for ((i=1; ! $([ "$TLC[i]" ]; echo $?); i++)) > > works too. > > Which, by the way, points out another reason you can't just use the > exit status of a command in a math context: command success/failure > are the reverse of true/false when taken as integer values. Cool! Thanks a lot! ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-04 2:43 ` Bart Schaefer 2014-11-04 4:51 ` Han Pingtian @ 2014-11-04 6:37 ` Ray Andrews 2014-11-04 7:13 ` Bart Schaefer 1 sibling, 1 reply; 19+ messages in thread From: Ray Andrews @ 2014-11-04 6:37 UTC (permalink / raw) To: zsh-users 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. Yes or no. If that answer is not acceptable as 'arithmetic', then what is it? ! $([ -n "$TLC[i]" ]; echo $?) 'echo $?' seems to receive a one or a zero, and that's 'arithmetic', so why does ! $([ -n "$TLC[i]" ]); ... not do exactly the same thing? Why do we need 'echo' to cough up a testable number? What does the '$?' do but carry the return value of the test? And what would break if the test just returned it's own return value with no need for help from 'echo $?' to restate it? When we use the 'if' form above, we don't need the help of 'echo $?' so why do we need it inside 'for (('? It seems like a pointless limitation. Maybe a trivial limitation, but still pointless. Indeed: [ -n "$TLC[i]" ] && echo "Yup, there's something in there" ... so the [] test doesn't even need 'if' to work, it *does* produce a testable return value, and IMHO that's 'arithmetic', so it should work in 'for (('. Which, by the way, points out another reason you can't just use the exit status of a command in a math context: command success/failure are the reverse of true/false when taken as integer values. Sure, but we get used to using '!' to reverse true/false, no? You hafta wonder, tho, how that convention ever got started. '0' is 'false', yet functions return '0' on success. AFAIK it has always been like that. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-04 6:37 ` Ray Andrews @ 2014-11-04 7:13 ` Bart Schaefer 2014-11-04 18:00 ` Ray Andrews 0 siblings, 1 reply; 19+ messages in thread From: Bart Schaefer @ 2014-11-04 7:13 UTC (permalink / raw) To: zsh-users 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. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: for loop question 2014-11-04 7:13 ` Bart Schaefer @ 2014-11-04 18:00 ` Ray Andrews 0 siblings, 0 replies; 19+ messages in thread From: Ray Andrews @ 2014-11-04 18:00 UTC (permalink / raw) To: zsh-users On 11/03/2014 11:13 PM, Bart Schaefer wrote: > } ... the test must surely produce an answer of some sort. > > The *nix command paradigm is organized around two concepts: Thanks Bart, that was very deeply informative, it helps me understand the bedrock on which this is all built. I asked an invalid question. It is not that an exit status is or isn't 'arithmetic', it is that an exit status is not part of a data stream. It is not *what* it is, but *where* it is that is relevant. I now see that: for ((i=1; ! $([ -n "$TLC[i]" ]; echo $?); i++)) ... is simple. ^ permalink raw reply [flat|nested] 19+ messages in thread
[parent not found: <141103184338.ZM32221__48957.5251042426$1415069142$gmane$org@torch.brasslantern.com>]
* Re: for loop question [not found] ` <141103184338.ZM32221__48957.5251042426$1415069142$gmane$org@torch.brasslantern.com> @ 2014-11-04 7:08 ` Stephane Chazelas 0 siblings, 0 replies; 19+ messages in thread From: Stephane Chazelas @ 2014-11-04 7:08 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-users 2014-11-03 18:43:38 -0800, Bart Schaefer: [...] > This could be written a LOT more plainly as > > for ((i=1; $([ -n "$TLC[i]" ]; echo $?) == 0; i++)) [...] Oh, for some reason, I didn't expect that to work assuming the $(...) would be expanded only once before the loop starts which of course was stupid. It was not my intention to obfuscate the code. -- Stephane ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2014-11-04 16:57 UTC | newest] Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-11-02 20:47 for loop question Ray Andrews 2014-11-02 21:00 ` Bart Schaefer [not found] ` <CAH+w=7aWS0xyS4CXRJBphDjesfUFQOsyJRMaG3RZRxmuj7xkOg__20885.3257158355$1414962125$gmane$org@mail.gmail.com> 2014-11-02 21:37 ` Stephane Chazelas 2014-11-02 22:44 ` Ray Andrews 2014-11-02 22:57 ` Bart Schaefer 2014-11-02 23:24 ` Oliver Kiddle 2014-11-03 0:07 ` Ray Andrews 2014-11-03 1:53 ` Mikael Magnusson 2014-11-03 2:22 ` Ray Andrews 2014-11-03 9:22 ` Mikael Magnusson 2014-11-03 17:26 ` Ray Andrews 2014-11-04 1:56 ` Han Pingtian 2014-11-04 2:29 ` Han Pingtian 2014-11-04 2:43 ` Bart Schaefer 2014-11-04 4:51 ` Han Pingtian 2014-11-04 6:37 ` Ray Andrews 2014-11-04 7:13 ` Bart Schaefer 2014-11-04 18:00 ` Ray Andrews [not found] ` <141103184338.ZM32221__48957.5251042426$1415069142$gmane$org@torch.brasslantern.com> 2014-11-04 7:08 ` Stephane Chazelas
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).