Toon posts:

[bash] voorkom dat extern programma gestopt wordt door CtrlC

Pagina: 1
Acties:

  • Gertjan
  • Registratie: oktober 2001
  • Laatst online: 29-07 09:06

Gertjan

mmmm, beer...

Topicstarter
Ik heb een bashscript geschreven waarin ik een loop een aantal externe applicaties aanroep om taken te verrichten. Die taken kunnen lang duren, zoals rsync. Ik wil in mijn script een manier inbouwen om het script netjes te stoppen:
  1. eenmaal op Ctrl-C drukken geeft een boodschap en zet een variabele. De volgende iteratie in de loop wordt niet gestart
  2. nogmaals op Ctrl-C drukken stopt het script per direct
Dit is op zich met een trap vrij gemakkelijk voor elkaar te krijgen. Het probleem is nu echer, dat als een Ctrl-C gegeven wordt terwijl het script met rsync bezig is, eerst de trap aangeroepen wordt, maar dat direct daarna de Ctrl-C alsnog doorgestuurd wordt naar rsync, waardoor die er mee stopt.

Een voorbeeld zegt meer dan 1000 woorden:

Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash

i_should_exit=0

function asap_exit() {

        if [ $i_should_exit == 1 ]; then
                echo "second SIGINT caught, exit immediately"
                exit 1
        else
                echo "SIGINT caught, will exit after this loop. Give another SIGINT to exit immediately"
                i_should_exit=1
        fi
}


trap asap_exit SIGINT

while [ /bin/true ]; do

        echo "sleeping"
        /bin/sleep 20
        echo "done"

        [ $i_should_exit == 1 ] && exit 1
done


Ik wil dus eigenlijk voor elkaar krijgen dat de /bin/sleep afgemaakt wordt bij 1x Ctrl-C, waarna de volgende iteratie van de loop stopt, maar dat de /bin/sleep bij een tweede Ctrl-C wel afgebroken wordt.

  • H!GHGuY
  • Registratie: december 2002
  • Niet online

H!GHGuY

Try and take over the world...

Lees even dit:
http://www.gnu.org/software/bash/manual/bashref.html#Signals

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
while true
do
  echo "sleeping"
  /bin/sleep 20 &
  wait
  if [ "$?" -gt 128 ]
  then
     wait
     echo "interrupted"
     exit
  fi
  echo "done"
done

ASSUME makes an ASS out of U and ME


  • Gertjan
  • Registratie: oktober 2001
  • Laatst online: 29-07 09:06

Gertjan

mmmm, beer...

Topicstarter
Dank voor je antwoord, dat voorbeeld doet inderdaad wat ik wil. Het stomme is dat ik wel met wait en asynchronous commands heb ge-experimenteerd, maar het elke keer niet werkend kreeg. Ik kwam er net achter dat dat kwam omdat mijn bashscript onder 'set -e' draait. $? is dan niet meer af te vangen, waardoor bovenstaande constructie niet goed werkt.
Ik ga 'set -e' weghalen en de exitcode zelf controleren.

  • Gertjan
  • Registratie: oktober 2001
  • Laatst online: 29-07 09:06

Gertjan

mmmm, beer...

Topicstarter
Ik kom er nog niet helemaal uit. De beschreven manier werkt goed voor commando's als sleep en dd, maar bij rsync gaat het nog niet goed. rsync krijgt namelijk toch nog de afgevangen SIGINT voor zijn kiezen en kapt er dan ook mee:

Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
trap "echo 'SIGINT caught'" SIGINT

while true
do
        echo "rsyncing"
        /usr/bin/rsync -aq $from $to &
        wait
        if [ "$?" -gt 128 ]
        then
                wait
                echo "interrupted"
                exit
        fi
        echo "done"
done


Het heeft vast iets te maken met subshells die bash wel gebruikt bij rsync en niet bij sleep, of andersom, of andere magie, maar ik kom er even niet uit. Iemand die een hint kan geven?

[Voor 3% gewijzigd door Gertjan op 07-10-2010 11:28]


  • H!GHGuY
  • Registratie: december 2002
  • Niet online

H!GHGuY

Try and take over the world...

Gertjan schreef op donderdag 07 oktober 2010 @ 11:23:
Ik kom er nog niet helemaal uit. De beschreven manier werkt goed voor commando's als sleep en dd, maar bij rsync gaat het nog niet goed. rsync krijgt namelijk toch nog de afgevangen SIGINT voor zijn kiezen en kapt er dan ook mee:

Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
trap "echo 'SIGINT caught'" SIGINT

while true
do
        echo "rsyncing"
        /usr/bin/rsync -aq $from $to &
        wait
        if [ "$?" -gt 128 ]
        then
                wait
                echo "interrupted"
                exit
        fi
        echo "done"
done


Het heeft vast iets te maken met subshells die bash wel gebruikt bij rsync en niet bij sleep, of andersom, of andere magie, maar ik kom er even niet uit. Iemand die een hint kan geven?
dd is geen builtin, net zoals rsync. Ben je zeker dat rsync geen vreemde dingen doet en dat het signal wel degelijk SIGINT is?

ASSUME makes an ASS out of U and ME


  • Gertjan
  • Registratie: oktober 2001
  • Laatst online: 29-07 09:06

Gertjan

mmmm, beer...

Topicstarter
H!GHGuY schreef op donderdag 07 oktober 2010 @ 12:37:
dd is geen builtin, net zoals rsync. Ben je zeker dat rsync geen vreemde dingen doet en dat het signal wel degelijk SIGINT is?
/bin/sleep is ook geen builtin, in tegenstelling tot sleep :). Maar /bin/sleep en dd doen beide wel wat ik verwacht, alleen rsync niet. Ik ben er niet zeker van dat rsync geen rare dingen doet. Ik ben er wel zeker van dat ik een SIGINT geef, omdat mijn trap echo "bla" SIGINT erop reageert. Ik heb niet het idee dat het aan rsync ligt, maar misschien wel aan de manier waarop bash rsync opstart. Bedankt voor het meedenken!

  • H!GHGuY
  • Registratie: december 2002
  • Niet online

H!GHGuY

Try and take over the world...

Gertjan schreef op donderdag 07 oktober 2010 @ 16:26:
[...]

/bin/sleep is ook geen builtin, in tegenstelling tot sleep :). Maar /bin/sleep en dd doen beide wel wat ik verwacht, alleen rsync niet. Ik ben er niet zeker van dat rsync geen rare dingen doet. Ik ben er wel zeker van dat ik een SIGINT geef, omdat mijn trap echo "bla" SIGINT erop reageert. Ik heb niet het idee dat het aan rsync ligt, maar misschien wel aan de manier waarop bash rsync opstart. Bedankt voor het meedenken!
Ik vind zo even deze bug terug:
http://www.mail-archive.com/bug-bash@gnu.org/msg01326.html

Daarin staat nog een handige tip: start even rsync via strace. Dan zie je meteen 2 dingen:
- doet rsync iets met signal handling?
- welk signal krijgt rsync?

ASSUME makes an ASS out of U and ME


  • Big Mama
  • Registratie: mei 2000
  • Laatst online: 13:51
- Je draait rsync in de background (doordat er een & achter de regel staat)

- Een achtergrondproces kun je nooit met CTRL+C afstoppen, want het signaal wat verstuurd wordt (SIGINT) komt via het toetsenbord via de terminal emulator bij het voorgrondproces aan.

- Stel dat het voorgrondproces dat niet afvangt en daardoor stopt (of via een trap erop reageert door 'exit' te doen), dan krijgen de kindertjes van het voorgrondproces (in dit voorbeeld 'rsync') een SIGHUP toegeslingerd. Kan rsync daar wel tegen, of is dat de oorzaak dat rsync stopt? Dit zou je kunnen testen door 'nohup rsync' te doen i.p.v. 'rsync').

Computers follow your orders, not your intentions.

Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee