[Python] While loop stopt niet

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • jdh009
  • Registratie: Juni 2002
  • Laatst online: 14:35

jdh009

FP ProMod
Topicstarter
Ik ben bezig met een startup script voor mijn Raspberry Pi die draait op Rasbian zonder GUI. Hiervoor heb ik twee scriptjes gemaakt om te testen of mijn idee werkt.

Het eerste script in init.d is gebaseerd op:
http://www.stuffaboutcode...-program-at-start-up.html

Script 1 staat in /etc/init.d en heet StartUpScript.
Bash: StartUpScript
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
27
28
29
30
31
32
33
#! /bin/sh
# /etc/init.d/StartUpScript 

### BEGIN INIT INFO
# Provides:          StartupPAI
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Script to start PAI Cameraprogram at boot
# Description:       Startup script that allows the Pi to load the camerasettings and timeframe for capturing hemispherical photos for calculating PAI of a forrest.
### END INIT INFO


# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting PAI timeseries"
    # run application you want to start
    sudo python /home/pi/test.py &
    ;;
  stop)
    echo "Stopping noip"
    # kill application you want to stop
    killall test.py
    ;;
  *)
    echo "Usage: /etc/init.d/timeseries.py {start|stop}"
    exit 1
    ;;
esac

exit 0


Script 2 staat in /home/pi en heet test.py:


Python: test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
 test = True
try:
    while test ==  True:

        testtekst = "test complete"
        print "testing"


except KeyboardInterrupt:
    test = False


print "loop Stopped"


De StartUpScript start automatisch op wanneer ik de Pi aanzet en zorgt er voor dat het tweede script start. Het tweede script zal ik later vervangen worden door verschillende commando's om de camera te besturen. Het probleem is nu echter dat dit tweede script (test.py) anders reageert wanneer ik hem handmatig start of via het andere script mee laat starten tijdens het booten.

Wanneer ik test.py via de commandline start kan ik hem stoppen via ctrl c, echter wanneer ik hem open via mijn andere script dan werkt mijn interurrupt niet meer. Met als gevolg dat ik niet door kan starten naar mijn user loginscherm van de pi. hij blijft dus in de testing loop hangen.

"Each event is preceded by Prophecy. But without the hero, there is no Event." - Zurin Arctus, the Underking | "Ad Nocendum Potentes sumus." - Me, 30 November 1999


Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Je start je script op in de achtergrond:
code:
1
sudo python /home/pi/test.py &


waardoor je keyboard-input niet meer bij je script terecht komt.

code:
1
sudo python /home/pi/test.py


zou wel moeten werken, hoewel ik er niet per se vanuit zou gaan dat er naar je keyboard wordt geluisterd tijdens het opstarten van je computer.

[ Voor 20% gewijzigd door ValHallASW op 15-09-2015 11:12 ]


Acties:
  • 0 Henk 'm!

  • jdh009
  • Registratie: Juni 2002
  • Laatst online: 14:35

jdh009

FP ProMod
Topicstarter
Bedankt,

Heb het meteen getest en het werkt, althans deels. Wanneer ik het script handmatig start via "sudo bash StartUpScript" dan pakt ie de ctrl+c wel, echter wanneer ik automatisch laat uitvoeren via boot niet.

code:
1
2
3
testing
^Cloop Stopped
pi@raspberrypi /etc/init.d $ sudo reboot



Afbeeldingslocatie: http://static.tweakers.net/ext/f/EWCqJ1TxyRh0wixmB9GYirxU/medium.jpg

[ Voor 3% gewijzigd door jdh009 op 15-09-2015 11:28 ]

"Each event is preceded by Prophecy. But without the hero, there is no Event." - Zurin Arctus, the Underking | "Ad Nocendum Potentes sumus." - Me, 30 November 1999


Acties:
  • 0 Henk 'm!

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 01:26

deadinspace

The what goes where now?

jdh009 schreef op dinsdag 15 september 2015 @ 11:27:
... pakt ie de ctrl+c wel, echter wanneer ik automatisch laat uitvoeren via boot niet.
Keyboard interrupts worden alleen verstrekt door een terminal die een "controlling terminal" voor het proces in kwestie is. De terminal die tijdens het booten wordt gebruikt (/dev/console) biedt geen controlling terminal. Ctrl-C gaat dus niet werken tijdens het booten.

Wat probeer je eigenlijk precies te bereiken? Ik vind een blokkerend init-script een rare constructie; init scripts zijn om het systeem te initialiseren (instellingen actief maken, services starten). Grote kans dat het op een handigere manier opgelost kan worden :)

Wat random andere feedback:
jdh009 schreef op dinsdag 15 september 2015 @ 10:17:
Script 1 staat in /etc/init.d en heet StartUpScript.
Probeer je scripts een meer omschrijvende naam mee te geven, want alle scripts in /etc/init.d zijn "startup scripts". Het init script voor de Apache webserver heet bv typisch "apache2".
start)
    echo "Starting PAI timeseries"
    # run application you want to start
    sudo python /home/pi/test.py &
Als je daadwerkelijk een service wil starten, kijk dan naar het start-stop-daemon commando (of naar voorbeeld-scripts die dat gebruiken). Dat is veel robuuster dan de aanpak uit je voorbeeldscript.
Python: test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
 test = True
try:
    while test ==  True:

        testtekst = "test complete"
        print "testing"


except KeyboardInterrupt:
    test = False


print "loop Stopped"
De vergelijking met True in "while test == True:" is overbodig, het is gebruikelijk en zelfs aan te raden om die weg te laten. "while test:" is dus beter.

Maar de hele test variabele is sowieso overbodig; op het moment dat je een KeyboardInterrupt krijgt wordt je while loop sowieso afgebroken. Je programma kan dus vereenvoudigd worden naar:
Python: test.py
1
2
3
4
5
try:
    while True:
        print "testing"
except KeyboardInterrupt:
    print "loop Stopped"

Acties:
  • 0 Henk 'm!

  • jdh009
  • Registratie: Juni 2002
  • Laatst online: 14:35

jdh009

FP ProMod
Topicstarter
deadinspace schreef op dinsdag 15 september 2015 @ 13:54:
[...]

Keyboard interrupts worden alleen verstrekt door een terminal die een "controlling terminal" voor het proces in kwestie is. De terminal die tijdens het booten wordt gebruikt (/dev/console) biedt geen controlling terminal. Ctrl-C gaat dus niet werken tijdens het booten.
Check, vandaar dat die dus niet reageert.
Wat probeer je eigenlijk precies te bereiken? Ik vind een blokkerend init-script een rare constructie; init scripts zijn om het systeem te initialiseren (instellingen actief maken, services starten). Grote kans dat het op een handigere manier opgelost kan worden :)
De rare constructie komt vooral door mijn gebrekkig (lees: basis) kennis linux, bash en python. Het doel is om mijn Pi uiteindelijk buiten achter te laten met een batterij/accu, wanneer ik dan het stroomknopje om klik dient de Pi op te starten en foto's te maken zonder input nodig te hebben. Echter wil ik hem wel kunnen gebruiken om daarna gewoon in te loggen als die niet aan het meten is en dus het script te annuleren als ik wel door wil gaan.

De init.d methode had ik via Google gevonden en was de enige methoden die ik betrouwbaar aan het werk kreeg. Ik egobuik hem daarom al een tijdje in het bos. Voordeel van deze methode is dat ik wel kan zien wat er op het scherm gebeurd (wanneer deze is aangesloten). Een achtergrond achtergrond proces vind ik net iets te tricky omdat ik soms best veel settings achteraf moet aanpassen. Je ziet dan waarmee die bezig is en wat de meetresultaten zijn. Helaas is het nadeel dat je dus je login blokkeert en via ssh het script aan en uit moet zetten. Door hem op afstand uit te lezen kan ik namelijk wel gewoon gebruiken en het scriptje op die manier uitzetten, en dus inloggen. Helaas is tijdens het uitvallen (accu leeg) een keer de SSH corrupt geraakt waardoor ik er niet meer in kon. Vandaar dat ik het script nu zo wil aanpassen dat ik hem via direct input kan stopzetten.
Wat random andere feedback:
Bedankt voor deze feedback :)

[ Voor 4% gewijzigd door jdh009 op 15-09-2015 15:10 ]

"Each event is preceded by Prophecy. But without the hero, there is no Event." - Zurin Arctus, the Underking | "Ad Nocendum Potentes sumus." - Me, 30 November 1999


  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 01:26

deadinspace

The what goes where now?

jdh009 schreef op dinsdag 15 september 2015 @ 14:42:
Het doel is om mijn Pi uiteindelijk buiten achter te laten met een batterij/accu, wanneer ik dan het stroomknopje om klik dient de Pi op te starten en foto's te maken zonder input nodig te hebben. Echter wil ik hem wel kunnen gebruiken om daarna gewoon in te loggen als die niet aan het meten is en dus het script te annuleren als ik wel door wil gaan.
Ok, wat misschien nog het eenvoudigst is, is om je programma automatisch te laten starten in "screen", dat is een programma waarmee je console-programma's in de achtergrond kan draaien en op elk moment weer naar de voorgrond kan halen. Screen in de achtergrond starten met een specifiek commando kan met
screen -d -m -t naampje; screen -X stuff 'commando\n'

Dit starten kan waarschijnlijk het handigst vanuit een cron job met @reboot. Over hoe het weer naar de voorgrond te halen is genoeg over te vinden ;)

Als je het netter/uitgebreider wil maken zie drie goede mogelijkheden:

1. Een achtergrondprocess (een service of daemon) dat automatisch opstart (bv via een init script). Input kan dan via een configfile, output via een logfile. Het geheel beïnvloeden gaat dan door de logfile te bestuderen, de configfile aan te passen en dan de daemon te herstarten (met iets als "service camcontrol restart"). Het is een niet erg interactieve methode, maar wel robuust en beproefd. Dit is hoe bijvoorbeeld de ssh server en webservers werken.

2. Een webapplicatie. Dit is eigenlijk een variatie op 1., maar in plaats van (of als toevoeging op) de configfile en logfile heb je een website waar je gegevens staan en je instellingen kunt aanpassen. Voordeel is dat dit relatief makkelijk interactief is te maken, en dat je het lekker vanaf je PC kunt bedienen. Nadeel is dat een netwerkverbinding nodig is voor bediening.

3. Een console applicatie die je automatisch op één van Linux virtuele consoles laat opstarten. Dit lijkt nog het meeste op wat je tot nu toe geprobeerd hebt, maar het grootste verschil is dat het programma dan na het booten wordt gestart in plaats van tijdens, en dat de console nog gewoon bruikbaar blijft. Linux ondersteunt meerdere virtuele consoles (standaard 6) waarvan er één tegelijk getoond wordt; je kunt switchen tussen die verschillende met alt-F1 t/m F6 (probeer maar). Het idee is dan je applicatie op één van die 6 te draaien. Dit was in het pre-systemd tijdperk (voor raspbian jessie) relatief makkelijk te realiseren, tegenwoordig weet ik niet hoe dat moet.

In het geval van optie 3 en eh... 0 heb je de mogelijkheid om informatie te printen en in te lezen van de gebruiker. Als je dat mooier/handiger wil doen kun je naar ncurses kijken (de enige realistische optie op dat gebied vziw).
Helaas is het nadeel dat je dus je login blokkeert en via ssh het script aan en uit moet zetten.
Na het weghalen van & uit dat script blokkeert dat script niet alleen de login, maar alles wat tijdens het opstarten nog na dat script komt. Hoeveel dat is hangt er een beetje van af (met moderne dependency-based inits zal het niet veel zijn), maar als ssh na jouw script aan de beurt is heb je een extra probleem ;)
Pagina: 1