Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: arrange 16 Května 2010, 12:17:15
-
Neví někdo prosím proč ((i++)) funguje pod bashem normálně jen pokud i se nerovná 0?
Příklad:# projedu i {-2..2}
# i++ vrací OK, ale pokud i=0, je problém
arrange@lucid-lean:/tmp$ i=-2; while [[ $i -lt 2 ]]; do ((i++)) && echo "$i; OK" || echo "$i; bad"; done
-1; OK
0; OK
1; bad
2; OK
arrange@lucid-lean:/tmp$ bash --version
GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
-
i++ nebo ++i vraci 0 kdyz je vysledek po teto operaci nenulovy... rekl bych ze je to proto aby si mohl prave detekovat tu 0 napr v cyklu nebo tak, alespon ja jsem to timto zpusobem kdysi pouzil.
-
i++ nebo ++i vraci 0 kdyz je vysledek po teto operaci nenulovy
To ale nesedí, i++ vrací 1 ($?=1) když je výsledek po operaci i=1, viz můj příklad.
Dělá mi to problém, protože potřebuji mít ve skriptu set -e, a vyhazuje mě to z něj v případě, který jsem popsal. Možná by to šlo "vyřešit" přes((i++)) || :
ale stejně by mě zajímalo, proč to tak je.
-
i=0;((i++))
echo $?
vypise se 1... proc? i++ se nejprve vyhodnoti pak inkrementuje cili vysledek operace je porad 0.
++i se nejprve inkrementuje pak vyhodnoti vysledek je 1.
Dela to protoze to tak proste je, z podstaty te operace.. naschval si dej i=0;echo $((i++))
bude vypisovat 0(i kdyz asi cekas 1). Pokud nepotrebujes hodnotu i pred tim nez ji inkrementujes (cili tu starou) je lepsi psat ++i. Je to udajne rychlejsi, i kdyz tohle plati u C nevim jestli obecne pro interpret bashe.
Taky nevim jestli se presne ptas na tohle :-[
-
Díky za nakopnutí, už jsem na to asi přišel:
chová se tak operace dělaná přes builtin let - kdykoli je výsledek=0, pak je návratová hodnota=1
Exit Status:
If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise..
((i++)) zřejmě implikuje let. Pokud je ta operace mimo let, chová se to klasicky. Příklad:$ i=-2; while [[ $i -lt 2 ]]; do i=$(($i + 1)) && echo "$i; OK" || echo "$i; bad"; done
-1; OK
0; OK
1; OK
2; OK
Pro mě z toho plyne: nepoužívat v těchto případech let :)
-
Dobre vedet.. ja mel dodneska za to ze
let pouze nahrazuje to "dvoji zavorkovani"
let i++ == ((i++))
-
Díky, evil. Připomíná mi to nějaký citát... :)
The Bride: [in Mandarin] Master...
Pai Mei: [in Mandarin; subtitled] Your Mandarin is lousy. It causes my ears great discomfort. You bray like an ass! You are not to speak unless spoken to! It is too much to hope but... do you speak Cantonese?
The Bride: [in English] I speak Japanese very well... as well as...
Pai Mei: [interupting] I didn't ask if you speak Japanese! I asked if you understood Cantonese.