Portál AbcLinuxu, 5. května 2025 13:11

Dotaz: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..

10.3.2013 20:38 karpi
shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
Přečteno: 306×
Odpovědět | Admin
Dobrý den, while se ve vztahu k proměnné NUM chová pokaždé jinak, jednou ji vynuluje, podruhé ne...:
#!/bin/bash

NUM=1

# 1) ztratí hodnotu NUM
# head -n 6 /proc/mounts | while read

# 2) zde hodnotu NUM udrží... 
while [ $NUM -lt 5 ]
    do
        echo "NUM: "$NUM
        NUM=$((NUM+1))
    done
   
echo -- $NUM

Výstup pro první a druhý případ vypadá takto:
alnagon ~ % 
alnagon ~ % ./scripts/01_pk_test_script.sh
NUM: 1
NUM: 2
NUM: 3
NUM: 4
NUM: 5
-- 1
alnagon ~ % 
alnagon ~ % ./scripts/01_pk_test_script.sh
NUM: 1
NUM: 2
NUM: 3
NUM: 4
NUM: 5
-- 6
alnagon ~ % 
alnagon ~ % 
Lze nějak docílit, aby hodnotu NUM zachoval i ve formě "while read" ?

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

10.3.2013 20:59 NN
Rozbalit Rozbalit vše Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
Odpovědět | | Sbalit | Link | Blokovat | Admin
head -n 6 /proc/mounts | while read
Tady neco chybi ne ?
10.3.2013 21:03 potato
Rozbalit Rozbalit vše Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
To určitě, ale i bez toho je jasný rozdíl: Roura vytváří subshell, takže nastavení proměnných v rouře se v hlavním shellu neprojeví. Je-li třeba nastavovat proměnné, musíš použít pouze přesměrování, nikoli roury -- je řada triků, které pomáhají v různých situacích, viz vyhledávání, řeší se to zde docela často...
10.3.2013 21:10 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
Odpovědět | | Sbalit | Link | Blokovat | Admin
Cele je to o tom, ze v pripade :
prikaz | while read ...

sa spusta subshell a premenna NUM je inicializovana mimo tohto subshellu, takze na nu cokolvek co sa deje v subshelli ( v slucke s while ), nema ziadny dosledok. Nasledne nemusi fungovat v kazdom shelli, ale bash minimalne to podporuje. Je to sposob, ako zabranit, aby sa vytvoril subshell.

#!/bin/bash
NUM=1

while read line
do
    echo "NUM: "$NUM
    echo "$line"
    NUM=$((NUM+1))
done< <(head -n6 /proc/mounts)
   
echo -- $NUM

Rovnako sa chovaju premenne aj vo funkciach, ak sa neexportuju.

10.3.2013 21:38 karpi
Rozbalit Rozbalit vše (SOLVED) Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
ano, ano,.. děkuji, to přesměrování funguje.

ještě jenom pro úplnost.. Šlo by to tedy nějak vyřešit pomocí toho "export" ? - Tedy já to zkoušel, ale nezafungovalo mi to..

10.3.2013 21:50 potato
Rozbalit Rozbalit vše Re: (SOLVED) Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
export s tím nemá co do činění, týká se předávání proměnných do podprocesů, nikoli naopak. Jelikož to potřebuješ naopak, jediný způsob je zbavit se subshellu (nebo případně proměnné někam zapsat, třeba přes declare -p, a pak zase načíst).

A s těmi funkcemi to stejně není pravda. Proměnné jsou v shellu implicitně globální a přiřazení uvnitř funkce mění globální hodnotu. Pokud chci lokální proměnné, tak to lze, ale musím je explicitně označit jako lokální pomocí local.
10.3.2013 22:04 karpi
Rozbalit Rozbalit vše Re: (SOLVED) Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
Děkuju znovu, toto vlákno zde, bylo opravdu přínosné (pro mě).

ps Odfajfkoval bych to jako solved, ale nevidím kde..
11.3.2013 00:59 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: (SOLVED) Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..

Pravda s tym exportom, musim priznat. :)

11.3.2013 01:13 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: (SOLVED) Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..

Taktiez je mozne pouzit cisto declare namiesto local, aj ked logickejsie a osobne tiez pouzivam local, ak chcem lokalne premenne. To len na doplnenie, ze je to ekvivalent, nie na opravu tvojho tvrdenia. To je spravne. ;)

#!/bin/bash

num=0

funkcia1(){
declare num
num=$RANDOM
echo  num z funkcie1:  $num
}


funkcia2(){
declare num
num=$RANDOM
echo  num z funkcie2:  $num
}

echo num: $num
funkcia1
echo num: $num
funkcia2
echo num: $num
10.3.2013 22:06 aaaaaaaaaaaaa
Rozbalit Rozbalit vše Re: shell while pokazde jinak; jednou proměnnou udrzi, podruhe ne..
Odpovědět | | Sbalit | Link | Blokovat | Admin

Pajpa (teda |) spusta subshell, rovnako ako zatvorky. A subshell nemoze ovplyvnit to, co sa deje v "hlavnom" shelli.

Riesenim je pouzivat tu hodnotu len v subshelli, teda napr.

prikaz | while read VARIABLE; do echo "Tu mi premenna $VARIABLE funguje"; done

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.