Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Názory k článku
Hrátky z řádky: pomocné soubory a zamykání

Harvie aura:51
7. 4. 2008 0:48 Nový

fajn

celé vlákno
Uzitecny clanek, konecne neco co jsem zatim nezkoumal...
marvin
marvin (neregistrovaný)
7. 4. 2008 2:50 Nový

lock

celé vlákno
napadlo mi toto:
1.skontrolujeme ci existuje foo-lockfile
2.ak ano->cakame kym sa uvolni zamok
ak nie-> echo $PID >>foo-lockfile
3.skontrolujeme ci cislo na zaciatku foo-lockfile je pid nasho procesu
ak ano-> zamok je nas
ak nie-> cakame kym sa uvolni zamok

to by malo stacit,ak si to dobre pamatam z unixovych cviceni:)
uživatel si přál zůstat v anonymitě
7. 4. 2008 3:05 Nový

Re: lock

celé vlákno
to by stacilo, kdyby vsechny programy pristupujici k tomu souboru pouzivaly stejny typ zamykani
peter
peter (neregistrovaný)
7. 4. 2008 9:27 Nový

Re: lock

celé vlákno
a co ked dva konkurencne procesy budu prebiehat takto:

p1: kontrola => subor neexistuje
p2: kontrola => subor neexistuje
p1: echo $PID >> foo-lockfile
p1: kontrola => cislo pid je nase => zamok je nas
p2: echo $PID >> foo-lockfile
p2: kontrola => cislo pid je nase => zamok je nas
pht
pht (neregistrovaný)
7. 4. 2008 9:49 Nový

Re: lock

celé vlákno
nebudou, protoze >> a ne >. v poslednim kroku budou v souboru dve pid.
peter
peter (neregistrovaný)
7. 4. 2008 11:20 Nový

Re: lock

celé vlákno
aha dik za objasnenie
Dan
Dan (neregistrovaný)
7. 4. 2008 18:36 Nový

Re: lock

celé vlákno
A co takhle:
p1: kontrola => subor neexistuje
p2: kontrola => subor neexistuje
p1: echo $PID >> foo-lockfile
p2: echo $PID >> foo-lockfile
p1: kontrola => cislo pid neni nase => zamok neni nas
p2: kontrola => cislo pid neni nase => zamok neni nas

Nebo proste situace, kdy p1 nestihne zapsat vse pred tim, nez zacne zapisovat p2 - pak se bude zapisovat na preskacku a pod.
Nic takoveho fungovat nebude...
Jediny zpusob, jak lze efektivne zamykat nejaky proces na nejakem zdroji, je pozadat o to jadro (mutexy semafory,...).
Ash
Ash (neregistrovaný)
7. 4. 2008 23:43 Nový

Re: lock

celé vlákno
Minimálně jeden z procesů p1 p2 si tam to své PID najde (jako první v pořadí v souboru). Takže výsledkem bude "cislo pid je nase" => zamok je nas.
Ondrej
Ondrej (neregistrovaný)
7. 4. 2008 9:56 Nový

Re: lock

celé vlákno
Kez uz robit zamok na fs, tak jedine pomocou mkdir
Pavel
Pavel (neregistrovaný)
7. 4. 2008 3:45 Nový

lock mkdir

celé vlákno
Vytvoreni adresare je atomicke a selze, pokud existuje. To se da celkem lehce vyuzit.
Proto staci zkouset vytvorit adresar a kontrolovat navratovy kod.


# Zamek
LOCKDIR='/tmp/x'

# Cekani na zamek
while (mkdir $LOCKDIR 2> /dev/null; [ "$?" '!=' 0 ] ); do
sleep 1
done

# Tady jsem sam, dokonce muzu pouzivat $LOCKDIR na sve docasne soubory.
date

# Odstraneni zamku
rm -rf $LOCKDIR
matej
matej (neregistrovaný)
7. 4. 2008 10:11 Nový

ln -s lock (was Re: lock mkdir)

celé vlákno
Podobne je atomicke aj vytvorenie linky.
LOCKFILE="/tmp/my.lock"
trap "rm -f $LOCKFILE" EXIT INT TERM

while ! ln -s lock $LOCKFILE; do
        echo >&2 "cannot obtain lock, waiting"
        sleep 1;
done

# urob co treba atomicky, potom zmaz lock
oldium
oldium (neregistrovaný)
7. 4. 2008 13:50 Nový

Re: ln -s lock (was Re: lock mkdir)

celé vlákno
Jedna takova ucelena implementace do Gentoo je v bugu http://bugs.gentoo.org/show_bug.cgi?id=118418. Vicenasobne zamykani pro Bash a zaroven automaticke odemykani pri ukoncovani shellu, dokonce i neco jako threadove promenne. Vse dulezite pro zamky je ve funkci trylock. Snad jedina externi zavislost je na bash_variable z /sbin/functions.sh (pouze Gentoo) pro predelani jmena na neco, co lze uchovat v Bashi. Dale staci nastavit promennou svclock na adresar, kde se ukladaji zamky, a uz muzete zacit pouzivat zamykani.

Zakladni myslenka je v pouziti `set -C; echo "$$ 1" > "$path"`, protoze parametr -C zakaze prepisovani souboru.
TomEeK
TomEeK (neregistrovaný)
7. 4. 2008 11:39 Nový

Re: lock mkdir

celé vlákno
A nebylo by lepsi misto volani bashe pouzival atomicka volani systemu?
tam by pak o nejakem predbihanim nemelo byt ani reci, ne?

cosi jako v Cecku toto:
char *filename;
int fd;

do {
filename = tempnam (NULL, "foo");
fd = open (filename, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0600);
free (filename);
} while (fd == -1);

Jen nevim jak bych to smolil v bashi.
Neporadite?
pht
pht (neregistrovaný)
7. 4. 2008 6:51 Nový

sleep na retry

celé vlákno
pouzivat konstantni sleep na cekani na nejaky zdroj (napr. zamek) je sebevrazda. obvykle se na to pouziva nejaka dostatecne rychle rostouci posloupnost (napriklad fibonacciho nebo nejaka exponenciela), pripadne nahodna hodnota v nejakem (zvetsujicim se) intervalu. taky je vhodne napriklad po peti neuspesnych pokusech skript ukoncit.
...
... (neregistrovaný)
7. 4. 2008 7:56 Nový

skvely serial

celé vlákno
vdaka za serial, clovek vzdy najde nieco uzitocne :-) aj po X rokoch pouzivania linuxu
uživatel si přál zůstat v anonymitě
7. 4. 2008 10:27 Nový

Proc tohle nefunguje?

celé vlákno
Mel jsem ted v gentoo problem s odinstalaci texinfo. Mel v prerm zvlastni konstrukci, ktera nefungovala ani, kdyz jsem udelal testovaci soubor. Jde mi o tohle:
#!/bin/bash

function tisk() {
  echo -e "line 1\nline 2\nline 3\nline 4"
}

while read nacteno;do echo "precetl $nacteno";done <(tisk)
Po spusteni to zahlasi chybu
./a: line 7: syntax error near unexpected token `<(tisk)'
./a: line 7: `while read nacteno;do echo "precetl $nacteno";done <(tisk)'
Pritom ale nasledujici kod probehne v poradku
#!/bin/bash

function tisk() {
  echo -e "line 1\nline 2\nline 3\nline 4"
}

cat <(tisk)
Mate nekdo tuseni, proc nefunguje presmerovani stdin do toho read?
Pichi aura:66
7. 4. 2008 10:50 Nový

Re: Proc tohle nefunguje?

celé vlákno
Konstrukce <() funguje v bashi spíše jako makro. spustí podproces a jeho výstup přesměruje do roury a tu rouru předá jako parametr. klíčové slovo done pochopitelně nečeká žádný parametr
$ echo <(echo "ahoj")
/dev/fd/63 
Místo
while read nacteno;do echo "precetl $nacteno";done <(tisk) 
prostě použij
tisk | while read nacteno;do echo "precetl $nacteno";done 
a je vymalováno.
uživatel si přál zůstat v anonymitě
7. 4. 2008 11:02 Nový

Re: Proc tohle nefunguje?

celé vlákno
dik za odpoved. Ja osobne pouzivam konstrukce ( prikaz1 ; prikaz2 ; prikaz3 ) | while read .... denne, vcetne zjednodusene formy prikaz | while ..... Tohle byl problem v jinem skriptu, ale privedlo me to na jednu myslenku. Pokud spustim prikaz | while read ... ; do A=neco;done, pak promenna A je zapomenuta a v dalsim kodu ji nepouziju. Tak jsem myslel, ze ten <() by mohl tenhle problem resit. while by se provadelo v aktualnim bashi akorat vstup by byl zmenenej z toho prikazu. Jina moznost me napadla zduplikovat STDIN a pak na stdin presmerovat vystup z toho programu neco jako exec 15<&0 <(tisk), ale tohle se mi taky nejak nepovedlo, stejne tak ani bash -c 'while read .....' <(tisk), coz by ale snad fungovat melo.

Nejakej napad, jak spustit while na vystup z nejakyho programu tak, aby ten while bezel v aktualnim bashi a nespustil podproces a zachovaly se tak nastaveni promennych v aktualnim bashi?

Pichi aura:66
7. 4. 2008 11:34 Nový

Re: Proc tohle nefunguje?

celé vlákno
Na to existuje jediné řešení: Použij sílu (nějaký skutečný programovací jazyk) Luku.
uživatel si přál zůstat v anonymitě
7. 4. 2008 11:39 Nový

Re: Proc tohle nefunguje?

celé vlákno
No, to je odpoved teda docela dost mimo misu:-) Osobne to spis resim tak, ze z toho prikaz | while ... udelat pomoci echo vystup ve tvaru PROM=VAL a pak davam eval. Ale je to takovy neohrabany, stejne, jako by bylo neohrabany psat 5 radkovy bash skript v nejakym vyssim jazyce.
Pichi aura:66
7. 4. 2008 15:15 Nový

Re: Proc tohle nefunguje?

celé vlákno
Když už se pustíš do
... udelat pomoci echo vystup ve tvaru PROM=VAL a pak davam eval ...
tak to už není pětiřádkový bash skript. No a když to nahradím tří řádkovým perl skriptem takový deseti řádkový bash a bez evalů, tak už se to vyplatí.
Ash
Ash (neregistrovaný)
7. 4. 2008 23:49 Nový

Re: Proc tohle nefunguje?

celé vlákno
> Tak jsem myslel, ze ten <() by mohl tenhle problem resit.

Ano, konstrukce <() se v bashi skutečně za tím to účelem (zachování proměnných) používá.
9x0
9x0 (neregistrovaný)
7. 4. 2008 21:50 Nový

Re: Proc tohle nefunguje?

celé vlákno
Pokial som to spravne pochopil, tak process substitution ti nahradi <(tisk) v kode za subor, kde sa nachadza vystup funkcie tisk. Budes tam mat teda nieco ako:

while read nacteno;do echo "precetl $nacteno";done /subor

Ty ale chces medzi done a <(tisk) vlozit <, aby si dostal

while read nacteno;do echo "precetl $nacteno";done < /subor

Vid http://tldp.org/LDP/abs/html/process-sub.html - maju tam priklad podobny tvojmu
Pichi aura:66
8. 4. 2008 9:23 Nový

Re: Proc tohle nefunguje?

celé vlákno
Nojo, funguje to:
$ function tisk() {
>   echo -e "line 1\nline 2\nline 3\nline 4"
> }
$
$ while read nacteno;do echo "precetl $nacteno";done < <(tisk)
precetl line 1
precetl line 2
precetl line 3
precetl line 4
$
Jan Molič
Jan Molič (neregistrovaný)
7. 4. 2008 10:46 Nový

flock

celé vlákno
Zkuste použít program "flock". Nahoru do skriptu umistete nasledujici kod, ktery "nahradi sama sebe sama sebou", jen s rozdilem, ze priste nastavi promennoou LOCKED, cimz obejde program flock a pokracuje dal. Pro BSDckare existuje obdobny program "setlock".
#!/bin/bash

if [[ -z "$LOCKED" ]]
then
   echo "ceka na zamek"
   touch ./tmp/lock
   export LOCKED=1
   exec flock ./tmp/lock "$0" "$@"
else
   echo "jedeme dal"
fi
PrasopesXXL
PrasopesXXL (neregistrovaný)
7. 4. 2008 16:05 Nový

mktemp v AIXu?

celé vlákno
Zdravim, vi nekdo ekvivalent mktemp pro AIX? Jde o produkcni stroj u zakaznika, takze rady typu "preloz si to pro AIX" nepripadaji v uvahu. Zatim to resim cislem procesu v suffixu, ale zarucene jedinecne jmeno by se mi libilo vice. Diky za kazdou radu!
uživatel si přál zůstat v anonymitě
8. 4. 2008 16:38 Nový

Re: mktemp v AIXu?

celé vlákno
zsh umi napriklad konstrukci =(prikaz), ktera vystup prikazu ulozi do docasneho souboru a vrati jeho nazev. (detailne jsem to nestudoval, ale bezi to pres open s creat|excl, takze je unikatnost zarucena)
still
still (neregistrovaný)
14. 4. 2008 14:09 Nový

Re: mktemp v AIXu?

celé vlákno
Tiez by ma to zaujimalo :)
JeromeHeretic
JeromeHeretic (neregistrovaný)
7. 4. 2008 23:42 Nový

Takova aprilova blbustka

celé vlákno
Sem kdysi stvoril tuhle kravinku, kdyz je teda zajem o ty shellovy konstrukce:
lynx --source http://www.ucw.cz/~jerome/blbosti/pacman.txt |bash
Vyzaduje bzip2 (asi esencialni v kazdem distru) a uudecode. VRELE DOPORUCUJI spustit v extra terminalu,
jinak je to obtizne killnutelne :-) Neni to zadna veda, ale co si tak pamatuju, tak oescapovat ten zasranej uuencode byla docela pakarna :-)
uživatel si přál zůstat v anonymitě
14. 5. 2008 18:00 Nový

Re: Takova aprilova blbustka

celé vlákno
a jak to souvisi s tematem???
MVA
MVA (neregistrovaný)
8. 4. 2008 14:37 Nový

lockfile

celé vlákno
tento problem jsem resil - navic prenositelne - unix,linux, windows(cygwin), ...
nakonec jsem nekde vygoogloval reseniktere udajne pouziva firefox:
jadro problemu je v primititvu, ktera se obvykle teoreticky nazyva TSL (test-and-set lock) - cim ji implementovat na ruznych OS, shellech,atd...
reseni od firefoxaku je vyuzit operaci "mv", ktera z principu sve funkce ASI MELA BYT atomicka - bud se soubor presune nebo to ma skocnit s chybou ("jiz existuje-chcete prepsat?", nema prava, atd...)
takze postup:

lockfile=filelock_xyz
tmplock=filelock_xyz_tmp$$ # me tohle staci :-)
touch $tmplock

# dulezita je volba -i (interactive) - aby se ptal, zda ma prespat a dostal odpoved "ne"
echo "n" | mv -i $tmplock $lockfile >&2

if [ ! -f $tmplock ]
then
echo "File lock made: $lockfile" >&2
break;
else
....

kazdopadne by me zajimal nazor nekoho kdo ma cas, chut videt do mv, resp. asi az jadra, zda je ta operace fakt atomicka... a tudiz funguje jako tsl, pokud ano tak si myslim, ze je to relativne rozumny zpusob jak to delat a hlavne nevyzaduje nejake speciality (zamykani na urovni fs, dalsi programy a jine "podivnosti" :-) )
uživatel si přál zůstat v anonymitě
8. 4. 2008 16:27 Nový

Re: lockfile

celé vlákno
test existence souboru a nasledny presun jsou dve nezavisle operace. samotny presun potom bez reci prepisuje puvodni soubor. pro tyto ucely je mv k nicemu.
Stanislav Vokac
Stanislav Vokac (neregistrovaný) ---.commerzbank.com
4. 3. 2010 12:06 Nový

Re: lockfile

celé vlákno

Co takhle „mv -i“ kterej se te zepta na konfirmaci prepsani. V noven shellu pak „pgrep mv | xargs kill –9“ a tim to na pozadi zabit a vyhodnotit navratovou hodnotu.
Mel by jsi tak navratovou hodnotu toho, jesli lockfile existuje i za pomoci prikazu mv.
Je to trochu prez ruku a dost zprasek, ale vidis, ze i pomoci mv to jde a tudiz neni jak rikas k nicemu.

martin dufka aura:43
13. 3. 2009 0:24 Nový

RE: Hrátky z řádky: pomocné soubory a zamykání

celé vlákno
Pokud jde jen o případ, aby se nestalo: "(kdy např. jeden program už čte to, co druhý ještě nedopsal)", tak bych možná využil raději práv než nějakých externích zámků.:


while [[ ! -a file || -w file ]]; do sleep 10; done

s tím, že ten zapisující po ukončení provede :
chmod 500 file

čímž uzavřel soubor pro zápis a je připraven pro čtení.
Zasílat nově přidané příspěvky e-mailem