$$ neden üst süreçle aynı kimliği döndürüyor?


160

Bash ile sorunum var ve nedenini bilmiyorum.
Kabuğun altına şunu giriyorum:

echo $$    ## print 2433
(echo $$)  ## also print 2433
(./getpid) ## print 2602

"getpid" şu anki pid'i almak için bir C programıdır, örneğin:

   int main() {
    printf("%d", (int)getpid());
    return 0;
   }

Beni şaşırtan şey şudur:

  1. "(Komut)" bir alt işlem olduğunu düşünüyorum (ben haklı mıyım?), Ve onun pid üst pid ile farklı olması gerektiğini düşünüyorum, ama aynı, neden ...
  2. Programımı parantez arasında pid göstermek için kullandığımda, gösterdiği pid farklı, doğru mu?
  3. '$$' makro gibi bir şey mi?

Bana yardım eder misiniz?


8
getpidAlt kabukta çalıştırılmasa bile farklı bir işlem kimliği göstereceğini unutmayın .
chepner

1
@ Mama echo $$ $BASHPID ; ( echo $$ $BASHPID )bunu yaptığını gösteriyor. Yuvarlak parantezler alt kabuk oluşturur. İfadeler değişken değerleri değiştirebilir ve üst kabuk bu değişiklikleri görmemelidir. Bu bir fork()işlem olarak uygulanır .
Ben

Yanıtlar:


224

$$bir alt kabukta üst öğenin işlem kimliğini döndürmek için tanımlanır; "Özel Parametreler" altındaki kılavuz sayfasından:

$ Kabuğun işlem kimliğine genişler. Bir () alt kabuğunda, alt kabuğun değil, geçerli kabuğun işlem kimliğine genişler.

In bash4, sen çocuğun işlem kimliğini alabilirsiniz BASHPID.

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634

17
"ebeveyn" biraz yanıltıcı (en azından benim için), aslında "üst düzey" kabuk. Örneğin: echo $$; (echo $$; (echo $$))aynı
pideyi

1
Sağ; I değeri (, değerini kalıtsal bir üst kabuktan söylenebilir olmalıdır kendi ebeveyn, vb). Üst düzey kabuk, (kabuk olmayan) üst işleminden miras almak yerine başlangıçta ayarlar.
chepner

$ Expands to the process ID of the shelltho? echo $sadece gerçekte $ yankılar.
Alexander Mills

@AlexanderMills Evet, evet; $tek başına bir parametre genişletmesi değildir. Man sayfası, özel parametrenin adına atıfta bulunur $; $tek başına genişlediğini iddia etmiyor .
chepner

Dürüst olmak gerekirse bunun ne anlama geldiğine dair hiçbir fikrim yok, ama echo $BASHPIDbash 4 ve 5'de çalışıyor (ancak MacOS'ta 3.2.57 sürümü değil)
Alexander Mills

81

Aşağıdakilerden birini kullanabilirsiniz.

  • $! son arka plan işleminin PID'sidir.
  • kill -0 $PID hala çalışıp çalışmadığını kontrol eder.
  • $$ geçerli kabuğun PID'sidir.

2
kill -0 $!Arka plan süreçlerinden bahsediyorsak ikinci mermi olmamalı mı? PIDvarsayılan olarak hiçbir şeye ayarlanmamıştır.
Isaac Freeman


4

getppid()C programınızın kabuğunuzun PID'sini yazdırmasını istiyorsanız deneyin .


2

Bilinen bir komutun PID'sini nasıl alacağınızı soruyorsanız, bunun gibi bir şeye benzeyecektir:

Aşağıdaki komutu verdiyseniz # Verilen komut *** idi

gg if = / dev / diskx / = / dev / disky


Sonra kullanırsınız:

PIDs=$(ps | grep dd | grep if | cut -b 1-5)

Burada ne olması gereken tüm benzersiz karakterleri bir alana bağlar ve bu alan kullanılarak yankılanabilir

echo $ PIDs


2

doğru pid almanın bu tek yönlü yolu

pid=$(cut -d' ' -f4 < /proc/self/stat)

aynı güzel alt için çalıştı

SUB(){
    pid=$(cut -d' ' -f4 < /proc/self/stat)
    echo "$$ != $pid"
}

echo "pid = $$"

(SUB)

çıktıyı kontrol et

pid = 8099
8099 != 8100

Güzel fikir, ama bu size kabuğun kesim çıktısını yakalamak için koşan çatalın pidini almaz mı? İki kez çalıştırırsam, bir kez echo $ (...) ve bir kez olmadan, o zaman farklı cevaplar alırım.
Martin Dorey
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.