Bash acceptă bifurcare similară cu C ' s furcă ()?

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

  • Parantezele creează un subshell , dar acel ' s furcă + așteptați. & 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; } &

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.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *