Portál AbcLinuxu, 10. května 2025 02:08

Dotaz: bash a globalni promenna

Amarok avatar 15.2.2009 19:10 Amarok | skóre: 33 | blog: blogoblog
bash a globalni promenna
Přečteno: 1079×
Odpovědět | Admin
Je tomu opravdu tak, ze v bashi neni mozno aktivne pracovat se zadnou globalni promennou?

I kdyz ve skriptu pouziju

export promenna=0

a ten skript spustim z terminalu, tak se to nechova jako globalni promenna. Jakmile je skript ukoncen, tak uz v aktualnim terminalu (ze ktereho jsem ho spoustel) ta promenna neni znama.

Samozrejme se to da vyresit nejakym souborem v /tmp apod., ale to bych nerad, jelikoz zapis na disk pro podobne ucely neberu jako zrovna idealni. Existuje nejake reseni?

Pro vysvetleni, k cemu to chci pouzit: klavesovou zkratkou spoustim skript, ktery spusti novou instanci terminalu (rxvt) a parametru -name predava "terminal_" + cislo, ktere se pri kazdem spusteni skriptu inkrementuje. Cili kdyz otevru za sebou 3 terminaly pomoci klavesy (=skriptu), tak nazvy budou "terminal_1", "terminal_2" a "terminal_3". Zatim to mam ve stavu, kdy se kazdy jmenuje "terminal_1", protoze se promenna nezvetsuje -- i kdyz ji ve skriptu na konci exportuju, tak se po ukonceni skriptu ztrati.
GNUniverse - May the source be with you...
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

15.2.2009 20:07 Raduz | skóre: 5
Rozbalit Rozbalit vše Re: bash a globalni promenna
Odpovědět | | Sbalit | Link | Blokovat | Admin
Skript se standardně spouští v samostatném subshellu s vlastním env, který je potomkem stávajícího shellu. Potomek nemůže ovlivnit prostředí rodiče. Pokud chceš změnit env ze skriptu, místo "bash skript" zkus ". skript". Tím spustíš skript ve stávající instanci shellu, a ovlivňuješ jeho proměnné.
15.2.2009 20:35 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Když provedete toto:
export a=blabla
bash
echo $blabla
... tak to bude fungovat, jak chcete.

Váš problém je ale ten, že proměnná není definována v prostředí procesu, který obsluhuje klávesové zkratky a spouští ty terminály.

Buď ten program přepište a nebo si budete muset udělat nějaký perzistentní čítač jinde (např. ten soubor), nebo to budete muset vydedukovat nějak automaticky v každém spuštěném shellu (např. ps a zjistit nejvyšší číslo terminálu).

In Ada the typical infinite loop would normally be terminated by detonation.
Amarok avatar 15.2.2009 20:47 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
Presne tak to je, trochu jsem se do toho zamotal.
Pouzit "ps" a secist tam bezici instance me uz taky napadlo, jen musim zjistit, jestli "ps" vypisuje i nazvy bezicich programu, ja potrebuju obsah WM_CLASS (coz si zjistuji pomoci xprop), to po me chce window manager (openbox).
Reseni "Buď ten program přepište" se mi taky libi, bohuzel nevim jak :D
Pouzit docasny soubor budu brat jako posledni moznost.
GNUniverse - May the source be with you...
15.2.2009 21:19 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
jestli "ps" vypisuje i nazvy bezicich programu
A co jiného by měl vypisovat?
In Ada the typical infinite loop would normally be terminated by detonation.
Amarok avatar 16.2.2009 08:42 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
To jsem se jen blbe vyjadril, ja prave myslel, jestli se tam da nekde vycist obsah WM_CLASS. Jeste se na to podivam, jit by to mohlo napr. i tak, kdybych zkusil spustit rxvt terminal pod vlastnim nazvem, tak aby se v bezicich procesech objevoval pod jinym nazvem nez defaultnim - protoze potrebuju rozlisit ty "moje" spustene skriptem a ostatni rxvt terminaly.
GNUniverse - May the source be with you...
17.2.2009 16:21 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Tak to nevím, tím spíš, že moc nevím co je to WM_CLASS :)

Pokud chcete spustit proces "pod jiným názvem", tak nejjednodušší cesta je symlink.
In Ada the typical infinite loop would normally be terminated by detonation.
Amarok avatar 17.2.2009 16:57 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
WM_CLASS je promenna z X prostredi. Kdyz se spusti v terminalu xprop a klikne se pak do nejakeho okna, tak jsou videt ruzne promenne hodnoty, konstanty apod. Window managery s tim pracuji pro rozlisovani jednotlivych oken.
Dik za ten symlink, ja uz zacinal prave koumat, jak ten proces prejmenovat.
GNUniverse - May the source be with you...
17.2.2009 19:32 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: bash a globalni promenna

Mi přijde, že když si třeba takhle

#!/usr/bin/python
import wnck, gtk

s = wnck.screen_get_default()
while gtk.events_pending():
    gtk.main_iteration()
for w in s.get_windows():
    print '%x' %w.get_xid(), w.get_name(), w.get_pid()

zjistím seznam všech oken, jejich názvy, XIDy a PIDy jejich procesů, tak to všechno přece nějak musí jít, ne? Nebo mi něco uniklo a mám si přečíst celé vlákno?

Amarok avatar 15.2.2009 20:43 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
No ja mam v tom skriptu nahore

#! /bin/bash

- cili i tohle bych mel odstranit, jestli jsem to pochopil spravne. To bohuzel ale nebude pak stejne fungovat "globalne", protoze ten skript spousti window manager, a ten pouzije napr. bash nebo sh, pro interpretaci skriptu.
GNUniverse - May the source be with you...
17.2.2009 09:19 Ash | skóre: 53
Rozbalit Rozbalit vše Re: bash a globalni promenna
Proč byste to odstraňoval, je to "komentář", komentáře při sourcování (. skript.sh) nevadí ;) Tahle direktiva poslouží jen pokud soubor nepředhazujete přímo tečce nebo bashi (. skript.sh nebo bash skript.sh).
15.2.2009 21:01 kuka
Rozbalit Rozbalit vše Re: bash a globalni promenna
Odpovědět | | Sbalit | Link | Blokovat | Admin

Co to je globalni promenna?  Toto resit pres promennou nepujde.  Co je spatneho na  souboru s citacem v /tmp?

Amarok avatar 15.2.2009 21:13 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
Globalni promennou nazyvam takovou promennou, ktera je dostupna v celem systemu v kteremkoli terminalu, a to jak pro cteni, tak pro zapis.
A proc beru /tmp jako posledni volbu je jednoduche: z nejakeho (mozna hloupeho) duvodu nemam rad, kdyz se hodne casto prepisuje jeden soubor, mam nejak pak pocit, ze by se tim driv vyskytly vadne bloky na HDD, nez bez pouzivani takovychto "pomucek". Precejen zapis na disk neni neomezeny, u RAM jsem o zadnem omezeni jeste necetl. To by mohlo byt klidne tema diskuze, jsem si jist, ze se v tom nazory budou asi hodne rozchazet.
GNUniverse - May the source be with you...
15.2.2009 21:18 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Tak si ten soubor dejte do /dev/shm (ramdisk). Nebo použijte nějakej proces-arbitr, kterej ta čísla eviduje a rozdává.
In Ada the typical infinite loop would normally be terminated by detonation.
Amarok avatar 16.2.2009 08:55 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
O /dev/shm jsem jeste ani neslysel, ted to ctu, to je presne reseni, ktere hledam, diky.
Zapisovani promennych na disk je podle me dost nevhodna technika, kdyz se ale aspon jedna o virtualni disk, tak mi to tak hrozne neprijde.
GNUniverse - May the source be with you...
17.2.2009 16:20 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
To není úplně pravda, neboť databázové programy dělají přesně to, že ukládají proměnné na disk.
In Ada the typical infinite loop would normally be terminated by detonation.
Amarok avatar 17.2.2009 16:52 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
Dost neefektivni teda... Domnivam se, ze to budou spis nejake promenne, ktere se pouzivaji jen obcas a ne "pri praci". A nebo to bude z bezpecnostniho duvodu, kdyby vypadl proud (coz nemeni nic na tom, ze to zpomaluje).
GNUniverse - May the source be with you...
17.2.2009 17:11 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Zpomalení nezaznamenáte, neboť nemáte extrémní požadavky na rychlost operace... spousta věcí se přes /tmp řeší -- od kompilace programů po "zobrazit soubor v programu" ve Vašem prohlížeči. V podstatě jediný reálný problém byste měl se synchronizací zápisů a čtení u toho souboru; pak tu může být ještě estetický problém, který asi právě řešíte :)
In Ada the typical infinite loop would normally be terminated by detonation.
17.2.2009 18:49 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: bash a globalni promenna
Mam podobne fobie/paranoje ukladat veci tak docasne ako je navratova hodnota nejakej premennej na disk, ale v poslednej dobe zacinam pochybovat nakolko su racionalne. Standardne jadro uklada na disk po 5s. Takze je len mala sanca, ze subor, ktory vznikne a zanikne v priebehu par desatin sekundy sa objavi na disku. Iba sa aktualizuje ctime pre /tmp. Ak je to vsak pocitac s viac vyuzivanym /tmp, tak by sa aktualizoval aj tak a po tych 5s sa prepisuje az vyslednou hodnotu bez ohladu na to kolkokrat sa zmenil v pamati.

Podobne ako program, ktory ktory casto (desiatky za sekundu) pripisuje malicky objem dat na koniec suboru. Je velmi otazne, ci ma vyznam riesit buffery v aplikacii a vysypavat ich hromadne, ked presne na tento ucel bola vymyslena a je pouzivana suborova cache v jadre. Aplikacnym bufferom sa usetri mnoztvo syscallov (a teda casu CPU), ale z pohladu opotrebovania disku je to fakt jedno, na ktorej urovni sa to riesi. Navyse aj disky uz dnes maju cache na podobne veci.

Takze mozno je to optimalizacia na mieste, kde za strasnu namahu sa skoro nic neusetri. Na stroji s dostatkom pamate moze pomoct ramdisk alebo shm, ale pokial zacnu vytlacat ostatne veci na swap, tak sa zase disk neusetril
If you hold a Unix shell up to your ear, you can you hear the C.
Amarok avatar 17.2.2009 19:42 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
Zrovna v mem skriptu se nejedna o docasny soubor, ale je tam ulozen trvale a pri kazdem spusteni skriptu se s nim pracuje a prepisuje se. Me to reseni pres /dev/shm prijde velmi dobre, jednoduse misto /tmp ve skriptu pisu /dev/shm a nic jineho jsem nemusel menit ani nastavovat.
V te souvislosti si rikam, proc se tedy shm nepouziva vic nez tmp? Aktualne mam v /tmp 137 Mb, v /dev/shm mam 4 kb (a to je pouze ten muj maly soubor, ktery ma sice jen 2 bajty, ale 4 kb bude asi cely souborovy blok).
GNUniverse - May the source be with you...
18.2.2009 07:25 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Tak si udělejte symlink tmp -> shm a bude se používat.
In Ada the typical infinite loop would normally be terminated by detonation.
18.2.2009 08:30 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: bash a globalni promenna

Myslím, že je to z historických důvodů. Adresář /tmp se hojně používal mnohem dřív, než vzniklo shm (tmpfs). Navíc, paměť byla vzácná a bylo potřeba jí šetřit.

Dnes je paměť levná, ale disky i nadále pomalé a stále ještě mechanické.

Stejně jako ty mám psychický problém, kdykoli se zbytečně šáhá na disk. Ten tvůj program bych řešil démonem, který by se nikdy neukončoval a tudíž si všechno pamatoval a hlavně nikdy nemusel startovat znovu. Reagoval by vždy okamžitě bez hrábnutí na disk.

Amarok avatar 18.2.2009 09:45 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
Jo to bude asi tak, proste pozustatek. Symlink by teda taky sel, jak navrhuje tady kolega pht :)
Zkusim ale ted daemon, jen tak ze zajimavosti, tady je takovy krakty priklad, jeste jsem nic podobneho ve skriptu nezkousel.
GNUniverse - May the source be with you...
18.2.2009 10:39 qvaq
Rozbalit Rozbalit vše Re: bash a globalni promenna

Ne kazdy si chce docasnymi daty zaplacavat RAM - klidne si tam udelej symlink, ale pak se mozna budes divit, az si tam nejaky program ulozi treba ISO image pripraveny k vypaleni. Disk jako synchronizacni prostredek se pouziva predevsim proto, ze to je velice jednoduche, prenositelne (/tmp musi byt na kazdem UNIXu, i kdyby tam zadny disk ani nebyl, /dev/shm ani ne na kazdem linuxu, rada lidi to vubec nepouziva, nemusi tam byt pravo pristupu pro bezne uzivatele,...) a usporne. Kdyby na tyto prkotiny kazdy program pouzival vlastniho demona, tak takovych zbytecnych demonu pobezi stovky - namatkou demon pro midnight commander, aby po jeho vypnuti zustal nastaveny adresar, pro ruzne "opravdove" demony demon udrzujici jejich lockfile, ...

Rozhodne nejde o nejaky pozustatek, ktery pouzivaji pouze blbecci, kterym ujel vlak. Kdyz chces, vymyslej znovu kolo, ale jak se rika "dvakrat mer" a vezmi v uvahu, ze nektere veci vymysleli a zdokonalovali lide mnohem schopnejsi nez ty (to neni nic osobniho, to plati temer pro kazdeho). Samozrejme to neznamena, ze maji vzdycky pravdu, ale je to velice caste :-)

Amarok avatar 18.2.2009 11:09 Amarok | skóre: 33 | blog: blogoblog
Rozbalit Rozbalit vše Re: bash a globalni promenna
/tmp na disku rozhodne rusit nebudu, pro vypalovani ho sam pouzivam a dvd se do mych 2 Gb RAM nevejde, to mi je jasne, to nemusis vysvetlovat. Daemona si vytvorim pro sebe, tobe ho posilat nebudu :) Neber taky osobne, proste sis chtel tvym prispevkem trochu rypnout.
GNUniverse - May the source be with you...
18.2.2009 13:43 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
/dev/shm by mělo být standardní podle posixu. Jinak i starší unixy nějakou formu tmpfs umožňují. Data, která mají být uchována na déle než jeden boot se obvykle cpou do ~/.nazevaplikace nebo něčeho takového.

Symlink /tmp do /dev/shm nebo jiného tmpfs se používá hlavně na embedded zařízeních, kde disk není a tudíž se musí zaplácávat RAM.
In Ada the typical infinite loop would normally be terminated by detonation.
18.2.2009 13:48 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Když potřebuji takového jednorázového démona, tak ho obvykle plesknu do /etc/inittab. Init se postará o spouštění, hlídání a kraviny typu opuštění terminálu. S odchytáváním signálů si není třeba extrémně lámat hlavu. U Vás bude spíš složité vymyslet jak s tím démonem komunikovat. Pokud vím, tak bash neumí poslouchat na socketech, což by ve Vašem případě bylo nejjednodušší.

In Ada the typical infinite loop would normally be terminated by detonation.
18.2.2009 14:10 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: bash a globalni promenna
Moze mu poslat signal. "Demon" si inkrementuje counter a spusti na pozadi terminal. Principialne podobne ako mam spraveny powerclick.
If you hold a Unix shell up to your ear, you can you hear the C.
18.2.2009 14:38 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
No, to by asi taky šlo. Alespoň v tomto konkrétním případě.
In Ada the typical infinite loop would normally be terminated by detonation.
19.2.2009 10:43 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
Takze je len mala sanca, ze subor, ktory vznikne a zanikne v priebehu par desatin sekundy sa objavi na disku. Iba sa aktualizuje ctime pre /tmp.
Jste si tím jist? Já jsem to tedy nijak podrobně nestudoval, ale řekl bych, že to není tak chytré, aby to z block cache odstranilo záznam všech sektorů které patří souboru, který jsem vymazal. Nebo jo?
In Ada the typical infinite loop would normally be terminated by detonation.
19.2.2009 12:37 Semo | skóre: 45 | blog: Semo
Rozbalit Rozbalit vše Re: bash a globalni promenna
Jste si tím jist?

Nie.

to není tak chytré, aby to z block cache odstranilo záznam všech sektorů které patří souboru, který jsem vymazal

Kto iny to ma vediet, ak nie jadro, cez ktore tecu vsetky poziadavky, ktore by mohli modifikovat subor? Pokial nemas zdielane diskove pole namountovane z niekolkych stran, tak jadro ma istotu, ze s tymto subotom za uz nemusi trapit. Nechce sa mi verit, ze by cela cache fungovala iba ako spozdovac. To by bola cela na nic.

"Odstranit" blok z cache nie je nic zlozite. Proste sa v nejakom zozname obsadenych stranok skrtne jedna (ta spravna) polozka - presunie sa zo zoznamu dirty stranok do zoznamu volnych. Stale je to radovo rychlejsie nez ju zapisovat na disk a skrtat az potom.
If you hold a Unix shell up to your ear, you can you hear the C.
19.2.2009 13:12 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: bash a globalni promenna

Je to celkem akademická debata, ale když udělám tenhle test

#!/usr/bin/python
#coding: utf-8
import time

fn = 'cislo'
counter = 0
file(fn, 'w').write('%d' %counter)

start = time.time()
while counter < 100000:
    counter = int(file(fn).read())
    file(fn, 'w').write('%d' %(counter+1))
print (time.time() - start)/counter

tak je vidět, že jedno takové zvýšení čítače v souboru vezme cca 430 mikrosekund. Je zajímavé, že v průběhu testu je zátěž skoro celá SYS, tj. žádná USER a žádná IOWAIT. Disk to tedy nebrzdí, spíš jaderná administrativa.

20.2.2009 10:26 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: bash a globalni promenna
OK, zdá se že máte pravdu:
# dd if=/dev/zero of=blah bs=2M count=20
20+0 records in
20+0 records out
41943040 bytes (42 MB) copied, 0.0742222 seconds, 565 MB/s

# losetup /dev/loop0 ./blah

# mkfs.xfs /dev/loop0
meta-data=/dev/loop0             isize=256    agcount=2, agsize=4096 blks
         =                       sectsz=512  
data     =                       bsize=4096   blocks=8192, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096  
log      =internal log           bsize=4096   blocks=1200, version=1
         =                       sectsz=512   sunit=0 blks
realtime =none                   extsz=65536  blocks=0, rtextents=0

# echo 100000 >/proc/sys/vm/dirty_writeback_centisecs 

# mkdir a
# mount -t xfs /dev/loop0 a

# echo qwertyuiop >a/a && rm a/a
# sync
# grep qwertyuiop blah
(nic)
In Ada the typical infinite loop would normally be terminated by detonation.
15.2.2009 21:41 kuka
Rozbalit Rozbalit vše Re: bash a globalni promenna

Nic takoveho jako globalni promenna dle uvedene definice neexistuje. O disk bych se opravdu neobaval, kolikrat se ten terminal bude spoustet - milionkrat? Soubory v /tmp se vzdycky pouzivaly, pouzivaji a jeste nejakou dobu asi pouzivat budou. Pokud to chces delat slozite, zrid si na to demona, se kterym budes komunikovat treba pres IPC a bude ti cislo terminalu udrzovat, ale je to doslova atomovka na vrabce.

18.2.2009 16:59 Ash | skóre: 53
Rozbalit Rozbalit vše Re: bash a globalni promenna
Asi tak, stačí udělat spouštění daného terminálu wrapper, který inkrementuje čítač v /tmp/foo a spustí terminál s příslušným oknem. Toť vše, práce dvě minuty, "přístupy na disk při spuštění terminálu" nemá smysl řešit, stejně se při spuštění terminálu na ten disk hrábne :))
17.2.2009 12:11 skonciljsem | skóre: 20
Rozbalit Rozbalit vše Re: bash a globalni promenna
Odpovědět | | Sbalit | Link | Blokovat | Admin

Co skript udělal se po jeho ukončení opravdu ztratí. Je tu ale možnost ho při spuštění includovat příkazem source (nebo tečka)

tedy source mujskript

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.