(bash) Komut dosyası A, B komut dosyasını bekleyin, ancak alt işlemini değil


9

Yani scriptA var hangi yapar:

ssh server1 -- scriptB &
ssh server2 -- scriptB &
ssh server3 -- scriptB &
wait
otherstuffhappens

ScriptB şunları yapar:

rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
exit

İstediğim sonuç scriptA, şu anda yaptığı komut dosyasının tüm örneklerinin bitmesini bekleyecek, ancak o kadar da önemli olmayan şeylerin arka plan rsync'lerini bekliyor. Bunlar beklemek istemediğim daha büyük dosyalardır.

Nohup, disown ve & arasındaki farkı okudum ve farklı kombinasyonları denedim, ancak aradığım sonucu elde edemiyorum.

Bu noktada oldukça şaşırdım. Herhangi bir yardım mutluluk duyacağız!

Yanıtlar:


15

Buradaki sorun sshd, komutun stdout'unu (en azından test ettiğim sürümle stderr değil) okuduğu borudaki dosya sonu için beklemesidir. Ve arka plan işi o boruya bir miras kalıyor.

Bu nedenle, bu soruna geçici bir çözüm bulmak için, o arka plan rsynckomutunun çıktısını bir dosyaya yönlendirin veya /dev/nullilgilenmiyorsanız. Ayrıca stderr'i yeniden yönlendirmelisiniz, çünkü sshd karşılık gelen boruyu beklemese bile, sshdçıkışlardan sonra boru kırılır, böylece rsyncstderr üzerine yazmaya çalışırsa öldürülür.

Yani:

rsync ... > /dev/null 2>&1 &

Karşılaştırmak:

$ time ssh localhost 'sleep 2 &'
ssh localhost 'sleep 2 &'  0.05s user 0.00s system 2% cpu 2.365 total
$ time ssh localhost 'sleep 2 > /dev/null &'
ssh localhost 'sleep 2 > /dev/null &'  0.04s user 0.00s system 12% cpu 0.349 total

Ve:

$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null &'; sleep 2; cat out
141  # ls by killed with SIGPIPE upon writing the error message
$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null 2>&1 &'; sleep 2; cat out
2    # ls exited normally after writing the error on /dev/null instead
     # of a broken pipe

4

Her ikisinin de üst öğesi olan bir komut dosyası yazın, sonra her ikisini de kolayca kontrol edebilirsiniz . Alternatif olarak , iki kanal arasında bir iletişim kanalı oluşturun .

Belirli arka plan işlerini özellikle yok saymak için PID'yi ( $!son arka plan iş PID'si) yakalayabilir ve wait $pidyalnızca o işin tamamlanmasını bekleyebilirsiniz.


3

-fİçin bayrak sshdüzeltmeleri sorunu. Test tarihi:

#!/bin/sh -e
echo $$_script__begin
( echo sleeping; sleep 2; echo slept )&
echo $$_script__end

Ben ssh localhost ./scriptkoştuğumda, ortaya çıkana kadar bekler slept. İle -fbayrak, en çıkar echo $$_script__endve sleptdaha sonra sonra arka planda görünür sshkomut döndü.


2

Bu, yukarı akış bugzilla # 2071'de açıklanan ve tartışılan OpenSSH sunucusunun bilinen bir sorunudur . Hatada, OpenSSH tarafında değil, aynı zamanda komut dosyası için de birkaç geçici çözüm önerilmektedir.

Komut dosyalarının çıktısını beklemek istiyorsanız , çok waitönce bir de eklemeniz gerekir .exitscriptB

Çıktıya aldırış etmiyorsan , sorunu aynı şekilde çözecek bazı varyasyonları nohupve IO yönlendirmeleri kullanın /dev/null.


1

Bunu deneyebilirsiniz. $!, en son yürütülen arka plan ardışık düzeninin / işleminin işlem kimliğini içeren varsayılan kabuk değişkenidir.

command1 &
lpid1=$!

command2 &
lpid2=$!

command3 &
lpid=$!

wait $lpid1  # waits for only the process with PID lpid1  to complete. 

exportDeğişken vb . Kullanarak betiğinize göre kullanmanız gerekir.


1

B'nin kendi arka plan süreçlerini beklemesi gerekiyor:

rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
wait
exit

Bu noktada, arka planda ikinci rsync'i çalıştırmayabilir ve waittamamen kullanmaktan kaçınabilirsiniz . Yapmam gerekiyordu OP hem çalıştırmak ne tahmin ediyorum rağmen rsynconları arkatasar anlamına olurdu paralel süreçler, hem (ile &) ve daha sonra kullanarak wait. Her durumda, bunun sorunu çözmenin en basit yolu olduğunu ve sorudaki bilgilere dayanarak seçeceğim yöntem olduğunu kabul ediyorum.
David Z
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.