Történt egyszer, hogy megszámoltam az egyszerre futó openvpn processeket kétféle módon, és a két módszer közötti különbségre lettem figyelmes:
root@konzumribanc:~ # ps ax | grep -c openvpn
22
root@konzumribanc:~ # ps ax | grep openvpn | wc -l
23
ebből következik, hogy:
root@konzumribanc:~ # ps ax | grep grep
root@konzumribanc:~ #
vagy egyszerűbben:
root@konzumribanc:~ # ps | grep grep
root@konzumribanc:~ #
továbbgondolva:
root@konzumribanc:~ # ps | grep grep
root@konzumribanc:~ #
root@konzumribanc:~ # ps | grep grep | tee
8922 pts/0 00:00:00 grep
root@konzumribanc:~ # ps | tee | grep grep
root@konzumribanc:~ #
Ez hogy lehet? A grep-nek kéne "látnia" saját magát, hiszen fut, nem?
Lehet, hogy valami sysctl miatt a pipe bufferel, majd mikor EOF-ot (vagy buffer overflowot) kap, akkor indítja a grepet?
root@konzumribanc:~ # ps --version && grep --version && bash --version && uname -sr
procps version 3.2.6
grep (GNU grep) 2.5.1
GNU bash, version 3.1.0(1)-release (i686-pc-linux-gnu)
Linux 2.4.33.3
Egyébként meg Devil-Linux 1.2.11 a disztró, de az 1.2.8-as verzióval is ugyanez van. Más (sid, gentoo, ubuntu) disztribbel jónak tűnt.
- 1384 megtekintés
Hozzászólások
valami ilyesmi van, hogyha 3 processzt hoz letre az ember, akkor lehet hogy az elso" ma'r le is futott, mig a 3-ik el sem indult:
- pipe letrehoz
- bash forkol
- pipe egyik fele dup2()-zve stdout-ra
- exec ps
- child lea'll
- pipe egyik fele beza'r
- masikpipe letrehoz
- bash forkol
- pipe masik fele dup2()-zve stdin-re
- masikpipe egyik fele dup2()-zve stdout-ra
- exec grep
- child leall
- maskpipe egyik fele beza'r
- bash forkol
- masikpipe masik fele dup2()-zve stdin-re
- exec tee
- child leall
itt az elso es a harmadik processznek nincs semmi kozos dolga, tehat minden tovabbi nelkul elofordulhat, hogy az elso" mar le is allt, mikozben a harmadik me'g el sem indult. de persze az is lehet (olyan a scheduling), hogy az elso" me'g fut, mikor a harmadik elindul.
pl:
apal@xeft:~$ echo | ps -A | wc -l
90
apal@xeft:~$ echo | ps -A | wc -l
89
apal@xeft:~$ echo | ps -A | wc -l
90
apal@xeft:~$ echo | ps -A | wc -l
90
apal@xeft:~$ echo | ps -A | wc -l
90
apal@xeft:~$ echo | ps -A | wc -l
90
apal@xeft:~$ echo | ps -A | wc -l
89
apal@xeft:~$ echo | ps -A | wc -l
93
apal@xeft:~$ echo | ps -A | wc -l
92
apal@xeft:~$ echo | ps -A | wc -l
93
vagy hasonloan:
apal@xeft:~$ for x in `seq 20` ; do echo | ps -A | wc -l ; done
92
93
93
92
92
93
93
92
92
93
93
93
92
93
93
92
92
93
93
93
- A hozzászóláshoz be kell jelentkezni
nincs valami 'ugyes' shell alias beallitva?
- A hozzászóláshoz be kell jelentkezni
ezzel mar en is talalkoztam, szal nem egyedi dolog.
neha egy ps faux | grep grep ottvan, neha nincs. :)
- A hozzászóláshoz be kell jelentkezni
confirming
(szerk.: tcsh alatt is volt)
- A hozzászóláshoz be kell jelentkezni
$ ps aux |grep grep
bandi 14036 0.0 0.2 3676 584 pts/0 R+ 00:16 0:00 grep grep
nekem megvan :P
--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
futtasd le egymas utan 10x
- A hozzászóláshoz be kell jelentkezni
egyszeru a magyarazat:
nem egyszerre indul a ps es a grep. bash elinditja a ps-t, fork, inditja a grepet, es a megfelelo in/out-okat osszekapcsolja. ha valamiert a grep lassan indul, akkor nem lesz benne a ps listaban.
de ha megvarom mig elindul a grep akkor mar mindig benne lesz:
$ for i in `seq 1 10`; do (sleep 1;ps aux) |grep grep; done | wc -l
10
update: ehe, ugyanezt irta apal is, bar o annyiban tevedett, hogy a processek nem allnak le, szepen megvarjak mig mindenki vegez:
$ (sleep 1;ps aux) |(grep ps;sleep 3)| grep ps
bandi 26335 0.0 0.2 3676 592 pts/0 S+ 03:03 0:00 grep ps
bandi 26336 0.0 0.2 3680 592 pts/0 S+ 03:03 0:00 grep ps
bandi 26337 0.0 0.3 2564 860 pts/0 R+ 03:03 0:00 ps aux
Elbandi
--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
processek nem allnak le, szepen megvarjak mig mindenki vegez:
ez annyiban lehet igaz, hogy a parent-nek be kell varnia, wait()-tel vagy waitpid()-del, tehat a bash valoban tudni fogja, mikor ki allt le. es amig nem konfirmalja, addig zombike'nt tenyleg ottmarad (ilyet is lehet latni neha). de a child definite leall (exit()), amit ve'gez a dolga'val - mivel ma's nem avatkozik bele a futtata'sa'ba.
(vagyis nem pontosan igy, mert a bash /meg altalaban a multitaszkos programok/ explicite nem va'r/nak/, hanem akkor wait()-tel, ha kap valami szignalt, asszem a sigchld-t)
- A hozzászóláshoz be kell jelentkezni
ps ax | grep -c openvpn | grep -v grep
Szűrd ki a grepet és mindig ugyanaz lesz az eredmény.
--
A nyúl egy igazi jellem. Ott ül a fűben, de akkor sem szívja!
- A hozzászóláshoz be kell jelentkezni
Ha mar grep, akkor akar ki is hasznalhatod, hogy regexp-et tud:
ps ax | grep '[o]penvpn'
- ebben a grap parancssorban az a szoveg, hogy "openvpn" nem szerepel (leven az o utan all egy zaro szogletes zarojel) - e miatt a grep onmagat nem talalja meg, de a regexp miatt a valodi openvpn-t tartalmazo sorokat igen.
A "mikor latszik vagy nem latszik" magyarazatahoz jobban kell tudni, hogy mikent mukodik a shell (raadasul nyilvan ahanyfele shell, annyifelekent lehet megcsinalni, bar nagy vonalakban termeszetesen valoszinuleg hasonloak), de foleg a kernel belsejet kell erteni. Es szintugy oprendszer fuggo a dolog, tegnap pl. egy HP-UX-on jatszottuk, hogy egy vegtelen ciklusban futtattunk hasonloan rosszul megirt ps / grep parancsot, es kb negyedora alatt egyszer lett meg a grep, a tobbi esetben nem latszott. Mas UNIX-like rendszerekben pedig sokkar surubben lehet belefutni. Azaz a megoldas, hogy az ilyet az ember a fentihez hasonloan korrekten kodolja le :-)
- A hozzászóláshoz be kell jelentkezni
Danke, jó tanulni mindig :-)
--
A nyúl egy igazi jellem. Ott ül a fűben, de akkor sem szívja!
- A hozzászóláshoz be kell jelentkezni
kicsit felcserélted az utolsó 2 grepet.
- A hozzászóláshoz be kell jelentkezni
Lehetséges, nem próbáltam, de szoktam használni, viszont Zahy megoldása több mint jó :-) Szóval van még mit tanulni jól.
--
A nyúl egy igazi jellem. Ott ül a fűben, de akkor sem szívja!
- A hozzászóláshoz be kell jelentkezni
Az ok egyszeru: a kernelben allithato a pipe size (lasd 'ulimit -a' kimenete). Alaphelyzetben 4K, de ulimit-tel rogton at is allitohato. Ha a ps kimenete belefer ebbe a 4K-ba, akkor a ps mar meghal, mire a grep futni kezd. Ha nem fer bele, akkor meg lathato lesz, mivel ha megtelik a buffer, akkor a kernel felfuggeszti az ado/iro process-t, es elinditja/ujrainditja a fogyaszto process-t.
Ezek egyszeru dolgok, igazan-nagyon, csak bele kell gondolni, hogy hogyan is mukodik a kernel. Amugy ha latsz valami operacios rendszerek konyvet (nem azt, amelyik a win95-ot meseli holtkezdoknek), akkor abban olvashatsz hasonlo -amugy kurvaerdekes- megoldasokrol, mint pl. IPC, message queue, utemezes, deadlock-kezeles, stb... Erdemes elolvasni, linuxosoknak (mar a komolyabbaknak ;) alapmu egy ilyen! Javaslom a tanenbaum-felet. Megdobbentoen jo!
- A hozzászóláshoz be kell jelentkezni
na, akkor valóban nem jártam messze az igazságtól a pufferrel meg sysctl dolgokal :)
- A hozzászóláshoz be kell jelentkezni
Én az ilyesmik elkerülése végett szoktam a ps-nek a -C opcióját használni:
fules@chaos:~$ ps -C getty
PID TTY TIME CMD
1732 tty1 00:00:00 getty
1733 tty2 00:00:00 getty
1734 tty3 00:00:00 getty
1735 tty4 00:00:00 getty
1736 tty5 00:00:00 getty
1737 tty6 00:00:00 getty
fules@chaos:~$ ps --no-heading -C getty
1732 tty1 00:00:00 getty
1733 tty2 00:00:00 getty
1734 tty3 00:00:00 getty
1735 tty4 00:00:00 getty
1736 tty5 00:00:00 getty
1737 tty6 00:00:00 getty
fules@chaos:~$ ps --no-heading -o '%p' -C getty
1732
1733
1734
1735
1736
1737
- A hozzászóláshoz be kell jelentkezni