Herhangi bir yumurtlanmış alt süreç başarısız olursa, hepsini öldürün ve


9

Benim betiğimde bir veri kümesini input_aa, input_ab vb.

# Execute program on each split file
for part in input_*; do
        python3 $part &
done
wait

Sorum iki katlıdır: Python işleminin başarısız olduğunu nasıl tespit edebilirim ve tespit edildiğinde, ortaya çıkan tüm çocukları nasıl öldürür ve senaryodan başarısızlıkla nasıl çıkarım?

Yanıtlar:


10

Bir işlem grubu kullanabilirsiniz:

set -m
(
   for part in input_*; do
     (python3 "$part" || kill 0) &
   done
   wait
)

set -m(ve isteğe bağlı POSIX kabuk özelliği, gerekli Unix kabuk özelliği) işleri kendi işlem gruplarında çalıştırır. Olarak bash, yash, zsh, mksh, alt dış kabuğunun işlerini olduğunu set -mdış böylece etkindir (...)ve bu içinde oluşturulan tüm süreçleri aynı süreç grubundaki yerleştirilecektir.

İçin dashve diğer ashesaslı kabukları, sadece üst düzey kabuk süreci çalışır. Bu nedenle, alt kabuğa konulmadığı sürece bu kod çalışır.

Bu AT&T kshveya eski SysV / Bourne kabuğunda işe yaramaz .

kill 0 geçerli işlem grubunun tüm üyelerine SIGTERM sinyali gönderir.


Bash. Neden bir shebang ekledim - gerekli kabuk net değil. İyi cevap
Jim Mcnamara

@jimmcnamara, işlerin bu bash, dash, yash, mksh, zsh. Temelde herhangi bir POSIX kabuğu ancak AT&T ksh. set -mPOSIX'te (altında) belirtilmiş, ancak isteğe bağlı bir özellik olarak belirtilmiştir.
Stéphane Chazelas

Solaris kullanıyorum. / bin / sh uçmaz.
jim mcnamara

@jimmcnamara, Solaris 10 ve öncesi için / bin / sh yok Bourne kabuğu (POSIX kabuğu değil) ve 11'de AT&T ksh. Dediğim gibi, bash, tire, yash, mksh, zsh olarak çalışıyor.
Stéphane Chazelas

1
@mikeserv, bu işlemi 1'e devreder, ancak süreç grubundan çıkarmaz. kill 0ebeveynleri ne olursa olsun süreç grubunun tüm üyelerini öldürür. Bkz ps -jsüreç grup kimlikleri görmek için.
Stéphane Chazelas

3

Bu bir örnektir. İhtiyacınız olanı tam olarak elde etmek için önce bu ile oynayın. Olduğu kadar kırılamaz.

#!/bin/bash
# Example of killing off all children

> killfile
> outfile.err
kill_em()
{
   echo 'killing all children ' > 2
   while read pid
   do
      kill -0 $pid && kill -9 $pid  # if still running kill it
   done < killfile
   exit 1
}

export grandparentpid=$$
trap 'kill_em' 6
for i in 2 2 3 4 5 6 7 8 9 10
do
        ( sleep $i && ls oinkle  >> outfile 2>> outfile.err &
          pid=$!
          echo $pid >> killfile
          wait $!
          [ $? -ne 0 ] && kill -6 $grandparentpid
        ) &
done
wait

ls oinkle(Makinemde) başarısız olacağından, bu kasıtlı olarak başarısız olacak şekilde ayarlanmıştır .

Başlangıç ​​komut dosyasıyla uğraştıktan sonra ihtiyacınız olanı elde ettiğinizde --- Değiştir:

for i in 2 2 3 4 5 6 7 8 9 10

için:

for part in input_* 

değişiklik:

sleep $i && ls oinkle 

için:

python3 $part 

Günlükleri kaydetmek için yönlendirmeler var. Onları istemeyebilirsiniz.


Biraz açık saçık. İşlerden biri diğeri başlamadan önce başarısız olursa, başlatılan killfileişlerin tüm pids'lerini içermeyebilirsiniz.
Stéphane Chazelas

Bir kaç kötü uygulama: alıntılanmamış değişkenler, isimler yerine sinyal numaralarının kullanımı, kullanıcı sinyali olarak USR1 / USR2 yerine sinyal 6'yı (örneğin Linux amd64'te ABRT) kullanın [ $? -ne 0 ]...
Stéphane Chazelas
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.