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

Název: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: 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:
Kód: [Vybrat]
# 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.
Název: Re: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: pajus 16 Května 2010, 13:02:03
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.
Název: Re: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: arrange 16 Května 2010, 13:11:03
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
Kód: [Vybrat]
((i++)) || :ale stejně by mě zajímalo, proč to tak je.
Název: Re: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: pajus 16 Května 2010, 13:21:41
Kód: [Vybrat]
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
Kód: [Vybrat]
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 :-[
Název: Re: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: arrange 16 Května 2010, 14:25:39
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
Citace: let.def
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:
Kód: [Vybrat]
$ 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  :) 
Název: Re: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: pajus 16 Května 2010, 14:49:44
Dobre vedet.. ja mel dodneska za to ze
let pouze nahrazuje to "dvoji zavorkovani"
Kód: [Vybrat]
let i++ == ((i++))
Název: Re: bash: ((i++)) vrací $?=1 pokud i=0?
Přispěvatel: arrange 16 Května 2010, 16:26:44
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.