Czy bash obsługuje rozwidlanie podobne do C ' s fork ()?

Mam skrypt, który chciałbym w pewnym momencie rozwidlić, więc działają dwie kopie tego samego skryptu.

Na przykład , Chciałbym, aby istniał następujący skrypt bash:

echo $$ do_fork() echo $$ 

Gdyby ten skrypt bash naprawdę istniał, oczekiwanym wynikiem byłoby:

<ProcessA PID> <ProcessB PID> <ProcessA PID> 

lub

<ProcessA PID> <ProcessA PID> <ProcessB PID> 

Czy jest coś, co mogę wstawić zamiast „do_fork ()”, aby to uzyskać rodzaj wyjścia czy spowodować, że skrypt bash wykona rozwidlenie w stylu C?

Odpowiedź

Tak. Rozwidlanie jest zapisywane jako &:

echo child & echo parent 

Może być mylące, że $$ nie jest PID procesu powłoki, to jest PID oryginalnego procesu powłoki. Celem zrobienia tego w ten sposób jest to, że $$ jest unikalnym identyfikatorem dla konkretnej instancji skryptu powłoki: nie zmienia się podczas wykonywania skryptu i różni się od $$ w każdym innym równolegle działającym scenariusz. Jednym ze sposobów uzyskania rzeczywistego PID procesu powłoki jest sh -c "echo $PPID".

Przepływ sterowania w powłoce nie jest taki sam jak w C. Jeśli w C „d pisz

first(); fork(); second(); third(); 

to odpowiednikiem powłoki jest

after_fork () { second; third; } first; after_fork & after_fork 

Prosta forma powłoki first; child & parent odpowiada zwykłemu idiomowi w C

first(); if (fork()) parent(); else child(); 

& i $$ istnieją i zachowują się w ten sposób w każdej powłoce w stylu Bournea oraz w (t) csh. $PPID nie istniało w oryginalnej wersji Bournea shell, ale jest w POSIX (więc jest w ash, bash, ksh, zsh,…).

Komentarze

  • Ale to ' s w zasadzie " fork + exec ", a nie tylko fork.
  • @mattdm: Uh? & to fork, tam ' nie jest zaangażowany w exec. Fork + exec jest uruchamiany po uruchomieniu polecenia zewnętrznego.
  • @mattdm: Ach, chyba rozumiem Cory próbuje. Tam ' nie ma exec, ale te dwa języki mają inny przepływ sterowania.
  • @Gilles: Bash operator kontrolny & uruchamia podpowłokę, w której wykonywane jest dane polecenie. Fork + exec. Możesz ' po prostu wstawić & bez poprzedzającego polecenia do wykonania.
  • Cóż, jeśli " Rozwidlenie jest pisane & " to prawdziwe stwierdzenie, możesz umieścić & w osobnej linii. Ale możesz ' t. Nie ' nie oznacza " rozwidlenia tutaj ". Oznacza to " wykonanie poprzedniego polecenia w tle w podpowłoce ".

Odpowiedź

Tak, nazywa się to podpowłokami . Kod powłoki w nawiasach jest uruchamiany jako podpowłoka (rozwidlenie). Jednak pierwsza powłoka zwykle czeka na zakończenie działania elementu podrzędnego. Możesz ustawić ją jako asynchroniczną za pomocą terminatora &. Zobacz to w akcji za pomocą czegoś takiego:

#!/bin/bash (sleep 2; echo "subsh 1")& echo "topsh" 

$ bash subsh.sh

Komentarze

  • Nawiasy tworzą podpowłokę , ale to ' s fork + wait. & to samo rozwidlenie. Jeśli chcesz wykonać więcej niż jeden potok w procesie potomnym, wystarczy ', aby użyć nawiasów klamrowych (które wykonują grupowanie bez tworzenia procesu potomnego): { sleep 2; echo child; } &

Odpowiedź

Nie ma natywnej bash (lub, o ile wiem, jakikolwiek inny typowy sposób powłoki * nix). Istnieje wiele sposobów tworzenia rozwidlonych procesów, które wykonują coś innego asynchronicznie, ale nie sądzę, aby było coś, co byłoby zgodne z dokładną semantyką wywołania systemowego fork ().

Typowe podejście niech twój skrypt najwyższego poziomu wyłączy pomocników, którzy wykonują tylko to, co chcesz, aby się rozdzieliły. Jeśli zrobisz $0 $@ & lub cokolwiek innego, zaczniesz od początku od nowa i musisz jakoś to rozgryźć.

Właściwie zaczynam wymyślać kilka sprytnych sposobów, w jakie można by to zrobić ….

Ale , zanim mój mózg zbytnio się tym przejmie, myślę, że całkiem dobra zasada brzmi: jeśli próbujesz napisać coś w powłoce, pełen sprytnych sztuczek i „chcesz mieć więcej funkcji językowych, czasu na przejście na prawdziwy język programowania .

Komentarze

  • Chociaż twój punkt widzenia jest dobrze zrozumiany – składnia bash ' jest prawdopodobnie trudna i ' Brak bardziej eleganckich struktur danych i funkcji Perla lub Pythona, bash jest tak realny, jak to tylko możliwe – w swojej domenie . Jest to język specyficzny dla domeny i argumentowałbym nawet lepiej (bardziej zwięźle, prościej) niż np. Python w wielu przypadkach. Czy potrafisz administrować pomieszczeniem pełnym systemów i nie znasz języka Python? Tak. Potrafisz to zrobić i nie znać się na bash [programowaniu]? Nie ' nie chciałbym próbować. Po 30 latach programowania powłoki mówię, że ' jest tak realne, jak to tylko możliwe. I tak, mówię w Pythonie. Ale nie ' nie myl dzieci.
  • To powiedziawszy, technicznie rzecz biorąc, bardziej podoba mi się ta odpowiedź. Stwierdzenie, że " & " jest odpowiedzią dla użytkownika ' s pytanie, " rozwidla się w jednym miejscu, tak że działają dwie kopie tego samego skryptu " mylący umysł. Zgodnie z instrukcją basha " & " to " … wykonuje [podane] polecenie w tle w podpowłoce. " Musi zakończyć polecenie i wymaga rozwidlenia (technicznie , w Linuksie clone ()), ale w tym momencie nie działają dwie kopie tego samego skryptu.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *