Bir kabuk komut dosyasında, arka planda bir komutu nasıl başlatabilirim (2) x saniye bekler (3) bu komut çalışırken ikinci bir komut çalıştırır?


11

Bunun olması gereken şey:

  1. A sürecini arka planda başlat
  2. x saniye bekle
  3. B sürecini ön planda başlat

Beklemeyi nasıl gerçekleştirebilirim?

Görüyorum ki 'uyku' her şeyi durduruyor gibi görünüyor ve aslında A sürecinin tamamen bitmesini 'beklemek' istemiyorum. Zaman bazlı döngüler gördüm ama daha temiz bir şey olup olmadığını merak ediyorum.


4
Zaten denediklerinize basit bir örnek vererek bu soruyu geliştirmenizi öneririz.
Andy Dalton

10
sleepA sürecini durduran izlenimi nereden alıyorsunuz ? Kullandığınız test sürecini gösterebilir veya bunun göstergesi olabilir misiniz? Süreç-A ise olduğu durdurulması, bunun arka planda çalışan ve oldukça ilgili her şeyden, bu nedenle durduruldu elde ederken terminalden okumaya çalışıyor olması daha olası sleep.
Charles Duffy

3
... ki eğer olduğunu durum, process_a </dev/null &onun Stdin ekler /dev/nullyerine TTY daha ve bu sorunu önlemek için yeterli olabilir.
Charles Duffy

Deneyimlerime göre uyku sadece mevcut süreci engeller ve böylece arka planda daha önce başlatılmış olan işlem &
MADforFUNandHappy

Yanıtlar:


28

Sorunuzu yanlış anlamadığım sürece, bu kısa komut dosyasıyla kolayca elde edilebilir:

#!/bin/bash

process_a &
sleep x
process_b

(ve waitbetiğinizin process_açıkmadan önce bitmesini beklemesini istiyorsanız sonuna bir satır daha ekleyin ).

Bunu bir komut dosyasına gerek kalmadan tek katmanlı olarak bile yapabilirsiniz (@BaardKopperud tarafından önerildiği gibi):

process_a & sleep x ; process_b

6
Bunun bashiçin gerekli olmadığını unutmayın, sisteminiz de dahil olmak üzere herhangi bir kabuk çalışacaktır sh, bu nedenle betiğiniz için bash bağımlılığı eklemenize gerek yoktur.
Stéphane Chazelas

4
Veya basitçe: process_a & sleep x; process_b
Baard Kopperud

9

Arka planda bir işlemi çalıştırmak için arka plan kontrol operatörünü (&) ve ikinci bir işlemi çalıştırmadan önce beklemek için sleepkomutu kullanabilirsiniz;

#!/usr/bin/env bash
# script.sh

command1 &
sleep x
command2

Aşağıda, zaman damgalı bazı iletileri yazdıran iki komut örneği verilmiştir:

#!/usr/bin/env bash

# Execute a process in the background
echo "$(date) - Running first process in the background..."
for i in {1..1000}; do
    echo "$(date) - I am running in the background";
    sleep 1;
done &> background-process-output.txt &

# Wait for 5 seconds
echo "$(date) - Sleeping..."
sleep 5 

# Execute a second process in the foreground
echo "$(date) - Running second process in the foreground..."
for i in {1..1000}; do
    echo "$(date) - I am running in the foreground";
    sleep 1;
done

İstediğiniz davranışı gösterdiğini doğrulamak için çalıştırın:

user@host:~$ bash script.sh

Fri Dec  1 13:41:10 CST 2017 - Running first process in the background...
Fri Dec  1 13:41:10 CST 2017 - Sleeping...
Fri Dec  1 13:41:15 CST 2017 - Running second process in the foreground...
Fri Dec  1 13:41:15 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:16 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:17 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:18 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:19 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:20 CST 2017 - I am running in the foreground
...
...
...

2
Soru "B sürecini ön planda başlatmayı" istiyor .
Sparhawk

1
@Sparhawk Wow. Tamamen yanlış okudum - açıklama yok. Uyarı için teşekkürler - kod düzeltildi. Kullanıcı adınızdan ciddi nostalji, btw.
Igal

1
Telaşa gerek yok! (Ayrıca kullanıcı adı başlangıçta bu bölüme bir referanstı , ancak daha sonra Eddings karakteri olduğunu fark ettim! Ve bu kitapları tekrar okumak istememi sağlıyor…)
Sparhawk

5

@ Dr01'in cevabını seviyorum ama çıkış kodunu kontrol etmiyor ve bu yüzden başarılı olup olmadığınızı bilmiyorsunuz.

İşte çıkış kodlarını kontrol eden bir çözüm.

#!/bin/bash

# run processes
process_a &
PID1=$!
sleep x
process_b &
PID2=$!
exitcode=0

# check the exitcode for process A
wait $PID1    
if (($? != 0)); then
    echo "ERROR: process_a exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi

# check the exitcode for process B
wait $PID2
if (($? != 0)); then
    echo "ERROR: process_b exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi
exit ${exitcode}

genellikle ben bir bash dizisinde PID saklamak ve sonra pid kontrol bir for döngüsü.


2
Bu çıkış kodlarını komut dosyanızın çıkış durumuna yansıtmak isteyebilirsinizA & sleep x; B; ret=$?; wait "$!" || exit "$ret"
Stéphane Chazelas

1
@ StéphaneChazelas iyi fikir. i biri veya her ikisi de başarısız olursa sıfır olmayan bir çıkış kodu döndürülmesini sağlamak için kodu güncelledi.
Trevor Boyd Smith

OP process_bön planda çalışmak istiyor . Muhtemelen process_açalışırken çıkış process_byapabilir, ancak yine waitde ön planın çıkış durumunu process_bnormal şekilde, $?doğrudan ile topladıktan sonra çıkış durumunu alabilirsiniz .
Peter Cordes
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.