Bash komut dosyalarını klasörde aynı anda çalıştırın


10

.shBir klasörde ( my_folder) beş Bash ( ) betiğimin olduğunu ve bunların şu şekilde adlandırıldığını varsayalım :

script_1.sh
script_2.sh
script_3.sh
script_4.sh
script_5.sh

Tüm bu komut dosyalarını birlikte çalıştırmaya başlayacak bir altıncı Bash komut dosyasını veya yalnızca bir satırı nasıl yazabilirim?

Birbiri ardına değil, aynı anda birlikte çalışmaya başlamak için beş komut dosyasına ihtiyacım var.


Yanıtlar:


12

GNU parallelbu tür şeyler için mükemmeldir. Şununla yükleyin sudo apt install parallelve ardından:

parallel -j0 ::: my_folder/*sh

-jT paralel olarak çalışan kaç süreçler kontrolleri ve -j0araçlar "hepsi". -j20Komut dosyalarını toplu olarak çalıştırmak için başka bir değere (örneğin ) ayarlayın .


1
not: pakette de parallelkomut var moreutils. Örnek kullanımı: parallel -j 20 -- my_folder/*.sh(GNU'da aksine parallel, -j0her seferinde komut bir çalışır).
jfs

1
@jfs iyi bir nokta. Ancak sudo apt install parallel, dosyanın /usr/bin/parallelGNU paralelinden biriyle değiştirileceğini unutmayın . Yüklediğiniz sürece, cevabımın önerdiği gibi, beklendiği gibi çalışması gerekir.
terdon

Evet, parallelcevabımı yazarken GNU paralel önermek için el kitabından başarısız komutlar denerken zor yoldan öğrendim .
jfs

9

Tüm komut dosyalarını aynı anda çalıştırmak için (paralel olarak) kullanın:

script_1.sh &
script_2.sh &
script_3.sh &
script_4.sh &
script_5.sh &

Birini arka arkaya çalıştırmak için (sırayla) kullanın:

script_1.sh &&
script_2.sh &&
script_3.sh &&
script_4.sh &&
script_5.sh

Yorumlar için geliştirme

Aynı anda çalıştırmak istediğiniz 200 komut dosyanız varsa (makinenin BTW'sini bozabilir) bu komut dosyasını kullanın:

#!/bin/bash
for Script in my_folder/*.sh ; do
    echo bash "$Script" &
done

Komut dosyası özniteliklerini şu komutla yürütülebilir dosyaya ayarlayın:

chmod a+x /path/to/script.sh

Komut dosyasını ilk kez çalıştırdığınızda, yürüteceği 200 komut dosyasının adlarını yankılandıracaktır. Mutlu olduğunuzda doğru adlar seçildiğinde komut dosyasını düzenleyin ve şu satırı değiştirin:

    echo bash "$Script" &

için:

    bash "$Script" &

Burada yanıtlandığı gibi bash betiğini diğerinden çağırabilmenin üç yolu vardır:

  1. Diğer komut dosyasını yürütülebilir yapın, #!/bin/bashen üstteki satırı ve dosyanın $PATHortam değişkeninin bulunduğu yolu ekleyin . Sonra normal bir komut olarak adlandırabilirsiniz;

  2. Veya şöyle kaynak komutuyla (diğer ad.) Çağırın source /path/to/script:;

  3. Veya yürütmek için bash komutunu kullanın /bin/bash /path/to/script:;

OP'nin durumunda, 200 komut dosyasından biri veya daha fazlası #!/bin/bashdosyadaki ilk satırını içermiyordu . Bu nedenle 3. seçenek kullanılmalıdır.


Aynı anda çalışan 200 Script

"Aynı anda çalışıyorlar mı" hakkında bir yorum yapılmıştır. Tipik bir 8 CPU sisteminde 25 komut dosyası aynı anda bir CPU paylaşacaktır, ancak zaman dilimi (milisaniye cinsinden ölçülür) bitene kadar aynı anda yalnızca bir komut dosyası yürütülür. Sonra bir sonraki iş milisaniye, daha sonra bir sonraki iş vb.

Gevşek terimlerle, CPU başına 25 işe eşit olan 8 CPU'da 200 işin "eşzamanlı olarak" çalıştığını, ancak "eşzamanlı olarak" çalışmadığını söyleyebiliriz:

thread states.png

Linux çekirdek zamanlayıcısından aşağıdaki resim ve yorumlar

time slice.png


teşekkür ederim .. şey benim gerçek durumda çalıştırmak için 200'den fazla komut dosyaları var olmasıdır. bu yüzden hepsini tek bir komutla (yani dosya adlarını yazmadan) çalıştırabileceğim bir yol var mı?
aaaaa

@aaaaa 200 komut dosyasının cevabını değiştirdim.
WinEunuuchs2Unix

Teşekkürler. işe yarar .. Son satırınıza eklemem gereken tek şey 'bash'. aksi takdirde 'izin reddedilir'.
aaaaa

1
@aaaaa Aslında 200'den fazla komut dosyasının aynı anda çalışmasını mı tercih edersiniz, yoksa bir kerede daha küçük bir sayının (örneğin, 10) çalıştırılmasını mı tercih edersiniz, diğerleri bir veya daha fazlası bittiğinde çalıştırmak için sıraya girer ve çalışmakta olan komut dosyası sayısı bu sayının altına düşüyor mu? (Bu tür çözümlerle ilgileniyorsanız, sorunuzu kaç tane komut dosyanız olduğunu, ne kadar süre çalışacaklarını, ne tür işleri yaptıklarını ve bunun gibi şeyleri içeren bilgilerle düzenlemenizi öneririz.)
Eliah Kagan

@aaaaa Geri bildiriminiz için teşekkür ederiz. bashKomut dosyasını çağırmak için önek eklemek için cevabı güncelledim .
WinEunuuchs2Unix

3

Bunun için bir araç var, okuyun man run-parts.

Örneğin, ben:

 run-parts ${visorhome}/pbackup.d/

Palm Pilot yedek komut dosyasında. ${visorhome}/pbackup.d/:

01PopulateJpilot  02Extract_Pedometer  03URLs  04google  05Books  06Weight  07Sec  08Bkgm 50hardlinks

1
@ eliah-kagan "Aynı anda" "200'den fazla komut dosyası" çalıştırmak akılsız görünüyor. Bir sistemi stres test etmek için iyi bir yol olabilir
waltinator

İyi bir nokta. Yine run-partsde OP istendiği gibi komutları bir kerede değil, sırayla yürüttüğünü belirtmek isteyebileceğinizi düşünüyorum . Yine de haklısınız, bir kerede 200 komut dosyası çalıştırmanın 5 çalıştırmayla aynı işlemi gerçekleştirmesi olası değildir - ve hepsini bir kerede çalıştırmak herhangi bir soruna neden olmasa bile, yine de gereksiz olabilir. OP'nin bu konuda tercihlerini netleştirmesini önermek için yorum yaptım .
Eliah Kagan

run-partskomut dosyalarını çalıştırmaz (adında bir nokta vardır:my_folder/*.sh
jfs

1
run-partssahip belirli very_ bazı garip nedenle dosya adı gereksinimleri. Uzantıları olan dosya adlarını başlatmaz, bu yüzden burada işe yaramayacağından korkuyorum.
terdon

1

Dizindeki tüm *.shkomut dosyalarını my_folderaynı anda çalıştırmak için xargs:

$ ls my_folder/*.sh | xargs -P0 -n1 bash

Eşzamanlı olarak yürütülen komut dosyası sayısını sınırlamak için 10:

$ ls my_folder/*.sh | xargs -P10 -n1 bash

lsBir betiğin çıktısını kullanmak kötü bir uygulamadır . Kullanımı findçok daha güvenlidir. Buradaki ilk öğe: mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29
Joe

@Joe genel olarak, doğrudur. Bu özel durumda hiçbir sorun görmüyorum.
jfs

Çünkü zaten biliyorsunuz. Daha sonra buraya gelen insanlar gelmeyebilir.
Joe

@Joe dogma'yı körü körüne takip etmiyor. Kendiniz için bir seçenek diğerinden daha iyi olduğunu düşünün.
jfs

Bu bir dogma değil. Onlara karşı alerjim var. Ama yayabileceđim ţeyleri gördüm. İnsan tarafından okunabilir çıktıların ayrıştırılması güvenilir değildir. Geliştiricilerin tutması için bir teşvik yok
Joe
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.