Am un script pe care aș dori să îl bifurcăm la un moment dat, astfel încât să ruleze două copii ale aceluiași script.
De exemplu , Aș dori să existe următorul script bash:
echo $$ do_fork() echo $$
Dacă acest script bash ar exista cu adevărat, rezultatul așteptat ar fi:
<ProcessA PID> <ProcessB PID> <ProcessA PID>
sau
<ProcessA PID> <ProcessA PID> <ProcessB PID>
Există ceva pe care să îl pot pune în locul lui „do_fork ()” pentru a obține acest lucru un fel de ieșire sau pentru a face ca scriptul bash să facă o bifurcare de tip C?
Răspuns
Da. Furcarea se scrie &
:
echo child & echo parent
Ceea ce vă poate deruta este că $$
nu este PID-ul procesului shell, este „PID-ul procesului shell original . Punctul de a face acest lucru este că $$
este un identificator unic pentru o anumită instanță a scriptului shell: nu se modifică în timpul execuției scriptului și este diferit de $$
în orice altă funcție simultană scenariu. O modalitate de a obține PID-ul real al procesului shell este sh -c "echo $PPID"
.
Fluxul de control din shell nu este același cu C. Dacă în C tu „d write
first(); fork(); second(); third();
atunci un echivalent shell este
after_fork () { second; third; } first; after_fork & after_fork
Forma shell simplă first; child & parent
corespunde limbajului C obișnuit
first(); if (fork()) parent(); else child();
&
și $$
există și se comportă astfel în fiecare shell în stil Bourne și în (t) csh. $PPID
nu a existat în orignal Bourne shell, dar este în POSIX (deci este „în cenușă, bash, ksh, zsh, …).
Comentarii
- Dar acel ' s practic " furcă + exec ", nu doar furcă.
- @mattdm: Uh?
&
este furcă, nu există ' nici un executant implicat. Fork + exec este atunci când lansați o comandă externă. - @mattdm: Ah, cred că văd ce Cory ajunge. Nu există ' nu
exec
, dar cele două limbi au un flux de control diferit. - @Gilles: The bash operatorul de control
&
pornește un subshell în care este executată comanda dată. Furcă + exec. Puteți ' pur și simplu pune&
fără o comandă anterioară de executat. - Ei bine, dacă " Forking este scris & " au fost o afirmație adevărată, ați putea pune
&
pe o linie de la sine. Dar nu poți ' t. ' nu înseamnă " aici ". Înseamnă că " execută comanda precedentă în fundal într-un subshell ".
Răspuns
Da, se numește sub-shell . Codul shell din paranteză este rulat ca subshell (furculiță). Cu toate acestea, primul shell așteaptă în mod normal ca copilul să se finalizeze. Puteți face acest lucru asincron folosind terminatorul &
. Vedeți-l în acțiune cu ceva de genul acesta:
#!/bin/bash (sleep 2; echo "subsh 1")& echo "topsh"
$ bash subsh.sh
Comentarii
Răspuns
Nu există nativ bash (sau, după știința mea, orice alt tipic * nix shell) mod de a face acest lucru. Există „o mulțime de modalități de a genera procese furcate care fac altceva asincron, dar nu cred că există ceva care să urmeze semantica exactă a apelului de sistem fork ().
Abordarea tipică ar fi fie ca scriptul dvs. de nivel superior să producă asistenți care fac exact munca pe care doriți să o împărțiți. Dacă faceți $0 $@ &
sau orice altceva, veți începe din nou la început și va trebui calculează asta cumva.
De fapt, încep să mă gândesc la mai multe moduri inteligente în care s-ar putea face exact asta …
Dar , înainte ca creierul meu să se lase prea încurcat cu asta, cred că o regulă destul de bună este: dacă încerci să scrii ceva în coajă și devine plin de trucuri inteligente și doriți mai multe funcții de limbaj, este timpul să treceți la un limbaj de programare real .
Comentarii
- Deși ideea dvs. este bine luată – bash ' este probabil că sintaxa este dificilă și ' lipsesc structurile de date și caracteristicile mai elegante ale Perl sau Python, bash este la fel de real pe cât devine- în domeniul său . Este un limbaj specific domeniului și aș argumenta chiar mai bine (mai succint, mai simplu) decât de exemplu Python în multe cazuri. Puteți administra o mulțime de sisteme și nu cunoașteți Python? Da. Poți să faci asta și să nu știi un pic de bash [programare]? Nu aș vrea ' să vreau să încerc. După 30 de ani de programare a shell-ului, vă spun că ' este la fel de real pe cât devine. Și da, vorbesc Python. Dar nu ' nu încurcați tinerii.
- Acestea fiind spuse, din punct de vedere tehnic îmi place mai mult acest răspuns. A spune că " & " este răspunsul pentru utilizator , " furcă la un moment dat, astfel încât două copii ale aceluiași script rulează " este pentru mine minte confuză. Ceea ce face " & ", conform manualului bash, este " … execută comanda [dată] în fundal într-un subshell. " Trebuie să termine o comandă și implică o bifurcație (tehnic , în Linux, o clonă ()), dar în acel moment nu rulează două copii ale aceluiași script.
&
este doar furculiță. Dacă doriți să executați mai multe conducte în procesul copil, ' este suficient pentru a utiliza acolade (care efectuează gruparea fără a crea un proces secundar):{ sleep 2; echo child; } &