Bash, C'nin çatalına () benzeyen çatalları destekliyor mu?


25

Bir noktada çatallamak istediğim bir betiğim var, böylece aynı betiğin iki kopyası çalışıyor.

Örneğin, aşağıdaki bash betiğinin olmasını istiyorum:

echo $$
do_fork()
echo $$

Bu bash betiği gerçekten mevcut olsaydı, beklenen çıktı şöyle olurdu:

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

veya

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

Bu tür çıktıları almak veya bash betiğinin C benzeri bir çatal yapmasına neden olmak için "do_fork ()" yerine koyabileceğim bir şey var mı?

Yanıtlar:


23

Evet. Forking yazıldığından &:

echo child & echo parent

Kafanızı karıştıran şey, $$kabuğun işleminin PID'si değil, orijinal kabuk işleminin PID'sidir. Bu şekilde yapmanın amacı $$, kabuk betiğinin belirli bir örneği için benzersiz bir tanımlayıcıdır: betiğin yürütülmesi sırasında değişmez ve $$eşzamanlı olarak çalışan tüm komut dosyalarından farklıdır . Kabuk işleminin gerçek PID'sini almanın bir yolu sh -c 'echo $PPID'.

Kabuktaki kontrol akışı C ile aynı değildir. C ise, yazarsanız

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

o zaman bir kabuk eşdeğeri

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

Basit kabuk formu first; child & parentolağan C deyimine tekabül eder

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

&ve $$her Bourne tarzı kabuğunda ve (t) csh içinde var olur ve bu şekilde davranırsınız. $PPIDorignal Bourne kabuğunda yoktu fakat POSIX'te (yani kül, bash, ksh, zsh,…).


3
Ama bu temelde "fork + exec", sadece çatal değil.
mattdm

@ mattdm: Uh? &çatal, dahil hiçbir yönetici yok. Fork + exec, harici bir komut başlattığınızda gerçekleşir.
Gilles 'SO- kötülükten vazgeç'

@ mattdm: Ah, sanırım Cory'nin neyle uğraştığını görüyorum. Yok exec, ancak iki dilin farklı kontrol akışı var.
Gilles 'SO- kötülük yapmayı bırak'

1
@Gilles: bash kontrol operatörü &, verilen komutun uygulandığı bir alt kabuğu başlatır. Çatal + exec. &Çalıştırmak için bir emir olmadan komut veremezsiniz .
mattdm

5
Eh, "Forking hecelendi &" doğru bir ifadeydi, &tek başına bir satır koyabilirsin . Ama yapamazsın. "Burada çatal" anlamına gelmez. "Önceki komutu bir alt kabukta arka planda yürüt" anlamına gelir.
mattdm

10

Evet, buna kabuk denir . Parantez içindeki kabuk kodu alt kabuk (çatal) olarak çalıştırılır. Ancak ilk kabuk normalde çocuğun tamamlanmasını bekler. &Sonlandırıcıyı kullanarak eşzamansız yapabilirsiniz . Şunun gibi bir şeyle çalışırken görün:

#!/bin/bash

(sleep 2; echo "subsh 1")&
echo "topsh"

$ bash subsh.sh


5
Parantezler alt kabuk oluşturur, fakat bu çatal + beklemektir. &yalnız çatal. Çocuk işleminde birden fazla boru hattı oluşturmak istiyorsanız, diş telleri kullanmak yeterlidir (çocuk işlem yapmadan gruplama yapar):{ sleep 2; echo child; } &
Gilles 'kötü kalıyor'

6

Bunu yapmanın hiçbir doğal bash (veya bildiğim kadarıyla, diğer herhangi bir tipik * nix kabuk) yolu yoktur. Çatallı işlemleri, zaman uyumsuz olarak başka bir şey yapan, çoğaltmak için birçok yol vardır, ancak fork () sistem çağrısının tam anlamını izleyen hiçbir şey olduğunu sanmıyorum.

Tipik bir yaklaşım, üst düzeydeki senaryonuzun sadece istediğiniz işi yapan yardımcıların ortaya çıkmasını sağlamaktır. Yaparsanız $0 $@ &ya da her neyse, tekrar en baştan başlayacaksınız ve bir şekilde bunu çözmeniz gerekecek.

Aslında birisinin bunu yapabileceği zekice yollar düşünmeye başlıyorum.

Ancak , beynim buna fazla dokunmadan önce, bence oldukça iyi bir kural: Kabuğa bir şeyler yazmaya çalışıyorsanız ve zekice numaralarla doluyorsanız ve daha fazla dil özelliği için geçiş yapmak istiyorsanız gerçek bir programlama dili .


2
Her ne kadar amacınız iyi ele alınsa da bash'ın sözdizimi tartışmalı olarak zor olsa da, Perl veya Python'un daha zarif veri yapıları ve özellikleri eksik olsa da, bash kendi alanında olduğu kadar gerçektir . Etki alanına özgü bir dildir ve birçok durumda örneğin Python'dan daha iyi (daha özlü, daha basit) tartışırdım. Python'u bilmeden bir oda dolusu sistemi yönetebilir misiniz? Evet. Bunu yapabilir ve bir bash yalaması [programlama] bilmiyor musunuz? Denemek istemem. 30 yıllık kabuk programlamanın ardından size olabildiğince gerçek olduğunu söylüyorum. Ve evet, Python'u konuşuyorum. Fakat gençleri şaşırtmayın.
Mike S,

2
Bununla birlikte, teknik olarak bu cevabı daha çok seviyorum. "&" Kullanıcının sorusunun cevabı olduğunu söylemek, "Bir noktada çatal, böylece aynı betiğin iki kopyası çalışıyor" aklımı karıştırıyor. Bash el kitabına göre "&" nin yaptığı şey, "... [verilen] komutunu arka planda bir kabuk altında çalıştırır." Bir komutu sonlandırması gerekir ve bir çatal (teknik olarak, Linux'ta bir klon ()) içermesi gerekir, ancak bu noktada aynı komut dosyasının iki kopyası çalışmıyor.
Mike S,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.