Sygnał przechwycenia skryptu Bash, ale poczekać na zakończenie procesów

głosy
37

obecnie piszę taki scenariusz bashowy jak ten:

foo(){
  while true
  do
    sleep 10
  done
}

bar(){
  while true
  do
    sleep 20
  done
}

foo &
bar &

wait

(Wiem, że nie ma sensu pisać takiego scenariusza, chodzi tylko o strukturę)

Teraz chcę dodać obsługę sygnału za pomocą trap -- <doSomething> RTMIN+1. Na początku to działa. Kiedy skrypt odbierze sygnał rtmin 1 robi coś, ale potem już istnieje (z kodem wyjścia 163, który jest numerem wysyłanego sygnału).

To nie jest zachowanie, którego chcę. Chcę, aby po otrzymaniu sygnału, skrypt nadal czekał na zakończenie procesów (w tym przypadku dwóch funkcji) (co oczywiście nie nastąpi w tym przypadku, ale skrypt powinien poczekać).

Próbowałem go dodać ; waitdo rzeczy, które powinny być zrobione podczas odbioru sygnału, ale to nie pomaga (lub robię coś złego).

Czy ktoś wie, jak osiągnąć pożądane zachowanie?

Dziękuję z góry i z najlepszymi życzeniami.

EDIT: Może bardziej precyzyjny przykład pomoże:

clock(){
        local prefix=C
        local interval=1
        while true
        do
                printf ${prefix} $(date '+%d.%m %H:%M:%S')\n
                sleep $interval
        done
}

volume(){
        prefix=V
                volstat=$(amixer get Master 2>/dev/null)

                echo $volstat | grep \[off\] >/dev/null && icon= #alternative: deaf:  mute: 

                vol=$(echo $volstat | grep -o \[[0-9]\+%\] | sed s/[^0-9]*//g;1q)

                if [ -z $icon ] ; then
                if [ $vol -gt 50 ]; then
                        icon=
                #elif [ $vol -gt 30 ]; then
                #       icon=
                else
                        icon=
                fi
                fi

                printf ${prefix}%s %3s%%\n $icon $vol
}

clock &
volume &

trap -- volume RTMIN+2

wait

Teraz RTMIN+2sygnał powinien ponownie uruchomić volumefunkcję, ale clockproces nie powinien zostać przerwany. (Do tej pory cały skrypt (ze wszystkimi podprocesami) jest zakończony po odebraniu sygnału)

Utwórz 30/04/2020 o 00:12
źródło użytkownik
W innych językach...                            


1 odpowiedzi

głosy
0

Coś przepisanego

W celu uniknięcia niektórych bezużytecznych widelców.

clock(){  local prefix=C interval=2
    while :;do
        printf "%s: %(%d.%m %H:%M:%S)T\n" $prefix -1
        sleep $interval
    done
}

volume(){  local prefix=V vol=()
    while IFS=':[]' read field playback val foo;do
        [ "$playback" ] && [ -z "${playback//*Playback*}" ] && [ "$val" ] &&
            vol+=(${val%\%})
    done < <(amixer get Master)
    suffix='%%'
    if [ "$vol" = "off" ] ;then
        icon="" #alternative: deaf:  mute: 
        suffix=''
    elif (( vol > 50 )) ;then  icon=""
    elif (( vol > 30 )) ;then  icon=""
    else                       icon=""
    fi
    printf -v values "%3s$suffix " ${vol[@]}
    printf "%s%s %s\n" $prefix "$icon" "$values"
}

clock & volume &

trap -- "volume" RTMIN+2
echo -e "To get status, run:\n  kill -RTMIN+2 $$"

while :;do wait ;done
Odpowiedział 09/06/2020 o 11:13
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more