Forum: PC-Programmierung Curses- TUI bei Login


von Matthias H. (matthias_h)


Lesenswert?

Hallo an die Wissenden,

auf einem Beaglebone mit ArchLinux läuft ein Python-Script, welches über 
rc.local gestartet wird. Ich möchte es irgendwie warten, wenn ich mich 
per SSH anmelde. Ich dachte da an ein kleines TUI mit Curses. Nur weiß 
ich im Moment nicht, wie ich das bewerkstelligen soll. Ich will im 
laufendem Python-Script ein paar Variablen ändern können und ein paar 
Ausgaben lesen. Kann mir da jemand einen Tip geben?

von tuttopossibilito (Gast)


Lesenswert?

Viele Möglichkeiten:

1. Ganz einfach: Das Skript schreibt seine Ausgaben in eine Log-Datei 
oder gleich ins Syslog. Eingaben / Konfiguration erhält es aus einer 
Datei, dessen Änderung das Skript detektiert und im Falle von neuen 
Werten diese einliest.

2. Etwas komplizierter: Das Skript wird in einer screen-Session 
gestartet. Ein Nutzer attached sich an diese Session und kann mit dem 
Skript (das dann eine Curses TUI hat) herumfummeln.

3. Ordentliches Design: Das Skript startet und lauscht lokal auf einer 
geeigneten Schnittstelle (IPC, UDP/IP, TCP/IP, was auch immer) und lässt 
sich von einem speziellen Client-Programm konfigurieren etc.

Von 1 nach 3 wirds komplizierter und gleichzeitig sauberer. Hängt davon 
ab, was Du willst und wieviel Arbeit Du invenstieren willst. Ich habe 
für unterschiedliche Anwendungen schon alle drei gemacht; es gibt 
bestimmt noch mehr Möglichkeiten. Was optimal ist, hängt immer von der 
Anwendung und deinem Geschmack ab.

Gruß
Hugohummelbert

von tuttopossibilito (Gast)


Lesenswert?

Achja, der Titel klingt so, als wolltest Du dieses "Bedienskript" (wie 
auch immer) direkt beim Login starten: Dann kann man das je nachdem wie 
sehr man dem ssh-Nutzer vertraut entweder einfach direkt als login-shell 
(/etc/passwd) eintragen oder in der jeweiligen .bashrc direkt an den 
Anfang stellen. Daran sollte es ja nicht scheitern.

von Klaus Maus (Gast)


Lesenswert?

Hi Matthias,

Matthias Herrmann schrieb:
> auf einem Beaglebone mit ArchLinux läuft ein Python-Script, welches über
> rc.local gestartet wird. Ich möchte es irgendwie warten, wenn ich mich
> per SSH anmelde. Ich dachte da an ein kleines TUI mit Curses. Nur weiß
> ich im Moment nicht, wie ich das bewerkstelligen soll. Ich will im
> laufendem Python-Script ein paar Variablen ändern können und ein paar
> Ausgaben lesen. Kann mir da jemand einen Tip geben?

Naja, UNIXe kennen etliche Möglichkeiten zur Interprozesskommunikation, 
Shared Memory, Domain- und Netzwerk-Sockets, ...

Für Deinen Anwendungsfall kannst Du aber eine Named Pipe benutzen:

"Server":
1
#!/usr/bin/python
2
import sys, os, time, exceptions
3
4
PIPE  = './pfeife'
5
DEBUG = 0
6
7
8
if __name__ == '__main__':
9
10
    variable = 12345
11
    buflist = list()
12
13
    try:
14
        os.mkfifo(PIPE)
15
    except exceptions.Exception, e:
16
        if DEBUG > 0: print >>sys.stderr, str(e)
17
18
    f_in  = os.fdopen(os.open(PIPE, os.O_RDONLY|os.O_NONBLOCK), 'r')
19
    f_out = os.fdopen(os.open(PIPE, os.O_WRONLY|os.O_NONBLOCK), 'w')
20
21
    while True:
22
        try:
23
            rd = f_in.read(1) # zeichenweise einlesen
24
            if rd:
25
26
                if rd == '\n': # Eingabezeile verarbeiten
27
                    buf = ''.join(buflist)
28
29
                    if DEBUG > 0:
30
                        print >>sys.stderr, buf
31
                        sys.stderr.flush()
32
                    if buf.startswith('+'):
33
                        variable += 1
34
                    elif buf.startswith('-'):
35
                        variable -= 1
36
                    elif buf.startswith('s'):
37
                        print >>f_out, variable
38
                        f_out.flush()
39
                        time.sleep(0.5) # hier muss der Client die Ausgabe abholen
40
                    else:
41
                        print >> sys.stderr, 'Eingabe nicht erkannt.'
42
43
                    buflist = list() # Eingabepuffer zuruecksetzen
44
45
                else:
46
                    buflist.append(rd)
47
48
            else: # if rd
49
                pass # nichts tun
50
                
51
        except exceptions.Exception, e:
52
            if DEBUG > 0: print >>sys.stderr, str(e)
53
54
        # hier kann der Server tun, was er tun soll
55
        pass

"Client":
1
#!/usr/bin/python
2
import sys, os, time, exceptions
3
4
PIPE  = './pfeife'
5
DEBUG = 0
6
7
PROMPT = """+ = erhoehe variable
8
- = vermindere variable
9
s = variable ausgeben
10
11
Dein Kommando? """
12
13
def cls(): 
14
    sys.stdout.write("\33[2J")
15
    sys.stdout.flush()
16
17
if __name__ == '__main__':
18
    buflist = list()
19
20
    try:
21
        os.mkfifo(PIPE)
22
    except exceptions.Exception, e:
23
        if DEBUG > 0: print >>sys.stderr, str(e)
24
25
    f_in  = os.fdopen(os.open(PIPE, os.O_RDONLY|os.O_NONBLOCK), 'r')
26
    f_out = os.fdopen(os.open(PIPE, os.O_WRONLY|os.O_NONBLOCK), 'w')
27
28
    while True:
29
        try:
30
            cls()
31
            print PROMPT
32
            i = raw_input('').strip()
33
            if i.startswith('q'): sys.exit()
34
            print >>f_out, i
35
            f_out.flush()
36
            time.sleep(0.1)
37
            f_in.flush()
38
            if i.startswith('s'):
39
                while True:
40
                    r = f_in.read(1)
41
                    if r:
42
                        if r == '\n':
43
                            print 'variable = ', ''.join(buflist)
44
                            buflist = list()
45
                            raw_input("Weiter mit <Return> ")
46
                            break
47
                        else:
48
                            buflist.append(r)
49
                
50
        except exceptions.Exception, e:
51
            if DEBUG > 0: print >>sys.stderr, str(e)

HTH,
Klaus

von Matthias H. (matthias_h)


Lesenswert?

Danke für die vielen Infos. Ich werde mir die einzelnen Möglichkeiten am 
Nachmittag mal anschauen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.