Zaten çalışan, mevcut olan bittikten sonra bir komut nasıl çalıştırılır?


32

Uzun sürecek bir senaryoyu başlatırsam, senaryoyu başlattıktan sonra kaçınılmaz olarak farkederim ve keşif bittiğinde bir çeşit alarm verebilmeyi isterdim.

Örneğin, eğer kaçarsam:

really_long_script.sh

ve enter tuşuna basın ... tamamlandığında başka bir komutu nasıl çalıştırabilirim?

Yanıtlar:


45

Birden fazla komutu ayırabilirsiniz ;, böylece sırayla yürütülürler, örneğin:

really_long_script.sh ; echo Finished

Bir sonraki programı sadece komut dosyası 0 dönüş kodu ile bitirdiyseniz (bu genellikle doğru şekilde çalıştığını gösterir), o zaman:

really_long_script.sh && echo OK

Bunun tersini istiyorsanız (yani, yalnızca geçerli komut başarısız olduğunda devam edin),

really_long_script.sh || echo FAILED

Komut dosyanızı bir arka planda çalıştırabilirsiniz (ancak dikkat edin, komut dosyası çıktısı ( stdoutve stderr) başka bir yere yönlendirmezseniz terminalinize gitmeye devam eder) ve sonra waitbunun için:

really_long_script.sh &
dosomethingelse
wait; echo Finished

Komut dosyasını zaten çalıştırdıysanız, onu askıya alabilir Ctrl-Zve ardından şöyle bir şey yürütebilirsiniz:

fg ; echo Finished

Nerede fg(ön plana askıya süreci getiriyor bgyapacak o ile başlayan hemen hemen gibi arka planda çalışmasına &)


@mlissner Bu davayı ele almak için cevabımı genişletti
aland

8
Yana fgbu devam eder işin döner değeri kullanabileceğiniz fg && echo Finishedkomut diğer komutu yürütmeden önce başarılı olmak istiyorum.
palswim

13

Bash'in iş kontrolünü de kullanabilirsiniz. Eğer başlarsan

$ really_long_script.sh

sonra askıya almak için ctrl + z tuşlarına basın:

^Z
[1]+  Stopped                 really_long_script.sh
$ bg

işi artalanda yeniden başlatmak için (tıpkı onunla başlamış gibi really_long_script.sh &). Sonra bu arka plan iş için bekleyebilir

$ wait N && echo "Successfully completed"

N, iş kimliğidir ( [1]yukarıda başka bir arka plan işinde çalışmamışsanız, muhtemelen 1'dir) .


11

İşlem geçerli tty'de çalışmazsa, şunu deneyin:

watch -g ps -opid -p <pid>; mycommand

2
Yaratıcı kullanımını seviyorum watch. Süper kısa cevap ve biri saati kullanmanın yeni ve kullanışlı bir yolunu öğrenir
Piotr Czapla

2

Bunun zor olmadığı ortaya çıkıyor: Mevcut komutu çalıştırırken sonraki komutu pencereye girebilirsiniz, enter tuşuna basın ve ilk komut bittiğinde, ikinci komut otomatik olarak çalışacaktır.

Sanırım daha zarif yollar var, ama bu işe yaramış gibi görünüyor.

Komut tamamlandıktan sonra bir uyarı çalıştırmak istiyorsanız, bu takma adları .bashrc'de oluşturabilir, sonra alertçalışırken çalışabilirsiniz:

 alias alert_helper='history|tail -n1|sed -e "s/^\s*[0-9]\+\s*//" -e "s/;\s*alert$//"'
 alias alert='notify-send -i gnome-terminal "Finished Terminal Job" "[$?] $(alert_helper)"'

7
Çalışan komut dosyası bir noktada girdi beklemiyorsa.
Daniel Beck

@Daniel - evet ... bu bir problem. Ateş etme.
mlissner

1

Bir süre önce başka bir sürecin sonunu bekleyecek bir senaryo yazdım. Doğru ayarlandığı taktirde , bunun NOISE_CMDgibi bir şey olabilir .notify-send ...DISPLAY

#!/bin/bash

NOISE_CMD="/usr/bin/mplayer -really-quiet $HOME/sfx/alarm-clock.mp3"

function usage() {
    echo "Usage: $(basename "$0") [ PROCESS_NAME [ PGREP_ARGS... ] ]"
    echo "Helpful arguments to pgrep are: -f -n -o -x"
}

if [ "$#" -gt 0 ] ; then
    PATTERN="$1"
    shift
    PIDS="$(pgrep "$PATTERN" "$@")"

    if [ -z "$PIDS" ] ; then
        echo "No process matching pattern \"$PATTERN\" found."
        exit
    fi

    echo "Waiting for:"
    pgrep -l "$PATTERN" "$@"

    for PID in $PIDS ; do
        while [ -d "/proc/$PID" ] ; do
            sleep 1
        done
    done
fi

exec $NOISE_CMD

Herhangi bir yayılma olmadan, hemen biraz gürültü yapın. Bu davranış, kolaylık olması için buna benzer bir şeye izin verir (aşağıdaki betiği çağırdığınızı söyleyin alarm.sh):

apt-get upgrade ; ~/bin/alarm.sh

Elbette böyle bir senaryo ile birçok komik şey yapabilirsiniz, bir örnek için alarm.shbeklemek durumunda kalmak alarm.sh, başka bir komut beklemek gibi. Veya hemen giriş yapmış bir kullanıcının bir görevinin bitmesinden hemen sonra bir komut çalıştırmak ...>: D

pgrepProses kimliğine bağımlılıktan kaçınmak ve kendiniz arama işlemini kabul etmek istiyorsanız, yukarıdaki betiğin eski bir sürümü ilginç olabilir :

#!/bin/bash

if [ "$#" -lt 2 -o ! -d "/proc/$1" ] ; then
  echo "Usage: $(basename "$0") PID COMMAND [ ARGUMENTS... ]"
  exit
fi

while [ -d "/proc/$1" ] ; do
  sleep 1
done

shift
exec "$@"

Biraz konu dışı, ancak benzer durumlarda kullanışlıdır: Biri reptyr, bazı (ana) kabuğundan bir işlemi "çalan" ve mevcut kabuğundan çalıştıran bir araçla ilgilenebilir . Benzer uygulamaları denedim ve reptyramaçlarım için en güzel ve en güvenilir olanıyım.

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.