[LUGOS] Spraviti spremenljivko iz subshella

Metod Kozelj metod.kozelj at lugos.si
Fri Dec 12 17:03:43 CET 2003


Howdy!

Boris Sagadin wrote:

>>>Ali je mozno kako spraviti spremenljivko, ki jo uporabljam v eni skripti,
>>>v parent shell?
>>>   
>>>
>>>      
>>>
>>Naceloma z export :)
>>
>>    
>>
>Ma, export ti naredi export v childe ne v parente ...
>---
>
>Torej, kako neko spremenljivko iz skripte spraviti v parent shell in ne
>v nek drug parent (drugo skripto, program, whatever, ki morda nekje v
>ozadju ze tece, morda celo v drugem shellu). Tu se strinjam, da bo vmesna
>datoteka potrebna.
>
>Baby steps varianta zate:
>
>mars:~$ echo $FOO
>
>mars:~$ cat > skripta
>#!/bin/bash
>FOO=`date`
>export FOO
>[CTRL+D]
>mars:~$ chmod +x skripta
>mars:~$ ./skripta 
>mars:~$ echo $FOO        
>
>mars:~$ source ./skripta
>

Čaki, čaki, sedaj moramo pa nekaj ločiti. Če narediš takole

$ ./skripta

potem ti parent (tvoj interaktivni bash) sforka childa (recimo bash, 
lahko pa tudi perl ali kaj drugega, če imaš tako nastavljeno v prvi 
vrstici dotične datoteke), ki potem zinterpretira vsebino datoteke. V 
tem primeru lahko govoriš o parentu (tvoj interaktivni shell) in childu 
(proces, ki poganja tvojo skripto).

Če pa narediš takole:

$ . ./skripta

oz.

$ source ./skripta

pa tvoj shell ne sforka childa, ampak je potem stvar dobesedno enaka 
tpikanju vsebine datoteke ./skripta v komandno vrstico. In tukaj ne 
moreš govoriti o exportanju variabel v parenta (ker ga nimaš oz. je to 
init). Načeloma pa se variabel ne da exportati parentu.

Razlog:
ko parent rodi childa (s fork() ), naredi kopijo svojega celotnega 
environmenta. Potem child packa po svoji kopiji in ko child odmre, je 
tudi njegov environment poslan v bitsink. NI variante, da bi child 
packal po pomnilniku, ki ga zaseda parent. No ja, čisto dobesedno ni 
tako, človek lahko uporablja shared memory med procesi in podobno, ampak 
to se ne dogaja na nivoju shell skript.

Torej  moraš najti način, da nekaj spraviš do parenta preko medija, ki 
ne izgine, ko child crkne. To je pa tipično file system (beri: datoteke) 
ali pa preko streamov (beri: stdin, stdout, fifo, ...).

Sicer pa mojo teorijo lahko enostavno poizkusiš:

--- foo.sh ---
#!/bin/sh
echo "PID=$$"
--- /foo.sh ---

Potem pa poganjaj po vrsti:

$ echo $$; ./foo.sh

in

$ echo $$; . ./foo.sh
oz.
$ echo $$; source ./foo.sh

($$ ti izpiše PID trenutnega procesa)

>P.S. /deflate ego
>

Enako velja zate.

-- 
Peace!
  Mkx

---- perl -e 'print $i=pack(c5,(41*2),sqrt(7056),(unpack(c,H)-2),oct(115),10);'





More information about the lugos-list mailing list