Daten|teiler
Kopieren als Kulturtechnik

Eine Python-Shell fürs Handy über WLAN

9. April 2010 von Christian Imhorst

Im Lieferumfang zu Python für S60-Handys von Nokia (PyS60) gibt es zwar schon eine Python-Shell fürs Handy über Bluetooth, aber was macht man, wenn kein Bluetooth, dafür aber WLAN vorhanden ist? Man richtet einfach eine Python-Shell über WLAN ein. Abgesehen davon steht die Shell über WLAN schneller, als man eine Bluetooth-Verbindung herstellen kann, weshalb sie sich auch eignet, selbst wenn Computer und Handy über Bluetooth-Schnittstellen verfügen.

Damit die Python-Shell über WLAN funktioniert, benötigt man das Programm netcat, das im Normalfall unter Gnu/Linux, Unix oder MacOS X schon installiert ist. Mit dem Befehl nc startet man das Kommando, um Daten mit TCP im Netzwerk zu übertragen. Folgendes Kommando funktioniert so nur unter Gnu/Linux:

stty raw -echo ; nc -l -p 1025 ; stty sane

Auf anderen Unix-Maschinen muss man den Schalter -p weglassen und einfach nur nc -l 1025 eingeben. Bevor man das Terminal via netcat in eine Python-Shell verwandeln kann, werden dessen Einstellungen mit dem Systembefehl stty neu gesetzt. Dabei schaltet die Option raw die Pufferung aus, damit eine Eingabe Zeichen für Zeichen an die Shell weitergereicht wird. Buchstaben werden dabei uninterpretiert weitergeleitet, was soviel heißt, dass es kein Newline-Zeichen oder ähnliches mehr gibt und Strg-D zum Beispiel keinen Datenstrom mehr beendet (End of File, EOF). Die Option echo verhindert, dass die eingegebene Taste nochmal im Terminal angezeigt wird. Anschließend startet netcat, um auf hereinkommende Verbindungsanfragen am Port 1025 zu lauschen. Im letzten Teil des Kommandos startet man wieder stty, diesmal aber mit der Option sane, um die Pufferung des Terminals wieder herzustellen, damit man die Python-Shell mit der Tastenkombination Strg-D (EOF) beenden kann.

Um netcat nicht vergeblich lauschen zu lassen, muss folgender Python-Code auf dem Telefon ausführt werden, damit die Verbindung hergestellt wird:

import btconsole
import sys
# Try to import 'btsocket' as 'socket'
try:
    sys.modules['socket'] = __import__('btsocket')
except ImportError:
    pass
import socket
 
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("192.168.0.10",1025))
btconsole.run_with_redirected_io(sock,btconsole.interact,None,None,locals())
sock.close()

Wichtig ist dabei, dass man die IP-Adresse des lauschenden Rechners eingibt. In dem Beispiel ist das 192.168.0.10, in der Realität wird es allerdings eine andere Adresse sein. Außerdem ist wichtig, dass ebenfalls Port 1025 benutzt wird. Man kann auch einen anderen Port wählen, den muss man dann nur auf beiden Seiten ändern. Wenn alles klappt, zeigt das Terminal eine Python-Shell auf dem Handy über WLAN:

Für die Vereinfachungen des Ganzen habe ich zwei Skripte geschrieben: Das erste Shell-Skript wifishell.sh wird auf dem Gnu/Linux-Rechner ausgeführt:

#!/bin/sh
# Script:      wifishell.sh
# Object:      Starts TCP/IP Console for S60 mobiles
#              afterwards start console.py on your S60
 
IP=$(ifconfig  | grep 'inet '| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')
PORT="1025"
 
echo "Your IP address is: $IP "
echo "Start now wifishell.py on your phone ..."
 
stty raw -echo ; nc -l -p 1025 ; stty sane

Im ersten Teil wird die IP-Adresse im eigenen Netzwerk ermittelt und in der Variable IP gespeichert. Dies gilt, wie gesagt, nur für Gnu/Linux-Rechner. Verwendet man ein Betriebssystem mit Free- oder OpenBSD, bzw. mit MacOS X, muss man stattdessen folgende Zeile in das Skript einfügen:

IP=$(ifconfig  | grep -E 'inet.[0-9]' | grep -v '127.0.0.1' |awk '{ print $2}')

Außerdem muss man darauf achten, dass der Aufruf von netcat im zweiten Teil des Skripts ohne den Schalter -p geschieht, wie das Beispiel auf einem Mac zeigt:

Als Benutzer von OpenSolaris verwendet man übrigens folgende Zeile im Skript:

IP=$(ifconfig -a | grep 'inet ' | grep -v '127.0.0.1' | awk '{ print $2}')

Das Gegenstück in Python wifishell.py muss auf das Handy gespielt werden. Wie alle anderen Python-Skripte auch, sollte es dort auf der Speicherkarte ins Verzeichnis E:\Python\ kopiert werden. Sobald wifishell.sh auf dem Gnu/Linux-Rechner oder der Unix-Maschine nach Anfragen auf dem Port 1025 lauscht, startet man über die Python-Shell auf dem Telefon das Skript wifishell.py, um eine Verbindung zum Terminal auf dem Computer herzustellen. Läuft alles glatt, verwandelt sich das Terminal in eine Python-Shell auf dem Handy.

# Script:      wifishell.py
# Object:      Starts TCP/IP Console for S60 mobiles
#              before start console.sh on your Gnu/Linux box
 
import btconsole, appuifw
import sys
try: # next lines important for select_access_point()
    sys.modules['socket'] = __import__('btsocket')
except ImportError:
    pass
import socket
 
ip = appuifw.query(u"IP address:", "text")
port = 1025
 
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((str(ip), port))
btconsole.run_with_redirected_io(sock,btconsole.interact,None,None,locals())
sock.close()

Geschrieben in Gnu/Linux, Python