mgolbs
Anmeldungsdatum: 11. Januar 2009
Beiträge: 269
Wohnort: Tirschenreuth - Löbau
|
Hallo, ich würde gern per Socket auf einen Mikrocontroller zugreifen und die AD bzw. IO Werte auslesen. (z.B. mit Ethersexprojekt, Pollin AVR-NET-IO und deren Firmware) Ein Python Skript macht das auch schon gut. Nur würde ich gern dieses in der Shell realisieren, da ich alte Linux Arm Geräte wie Zaurus SL5500 oder Psion Netbook Pro habe, und diese als mobilen Datenspeicher mit vernünftigen Laufzeiten nutzen würde. Die Shell in irgend einer Form ist da immer drauf. Sich Python drauf zu bringen, wird bei den alten Systemen schwierig. Man könnte es in C, Freepascal... umsetzen, nur dann muss man den richtigen Cross für Arm konfigurieren. Von einer Shellvariante erhoffe ich mir da mehr Unabhängigkeit, flexibler einzusetzen. Über die Suche im Forum habe ich keine Aussagen zu Socket und Shell passend gefunden. Auch www.google.de liefert nur Aussagen wie: sehr bedingt möglich... Geht Socket in der Shell überhaupt prinzipiell, und wo liegen die Grenzen? Über Tipps und Infos würde ich mich sehr freuen. Gruß und Dank Markus
|
theinlein
Anmeldungsdatum: 29. Dezember 2007
Beiträge: 1279
|
Hi, die Shell ist keine Programmiersprache/Scriptsprache, wie es z.B. Python ist. Wenn du direkt mit der Shell arbeiten willst, kannst du nur einfache Datenströme per TCP hin und herschieben. Dazu nimmt man telnet oder auch netcat in die man Daten z.B. per Pipe übergeben kann. Wenn du den Onkel Microcontroller gut kennst, und dessen Anfragen mittels Meldungen im ASCII bewerkstelligt werden können,
dann mache in einer Shell Commandline telnet ipadresse portnummer mal eine Verbindung auf und tippe den Request an den Controller per Hand ein (... wie gesagt, falls du das Bauen der Meldung per Zeicheneingabe hinbekommst) Wenn der MC antwortet, siehst du das in den ausgegebenen Zeilen.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
theinlein schrieb: die Shell ist keine Programmiersprache/Scriptsprache, wie es z.B. Python ist.
Genau. Das wird die Sache etwas schwieriger machen - aber nicht unmöglich.
Wenn du direkt mit der Shell arbeiten willst, kannst du nur einfache Datenströme per TCP hin und herschieben.
Streng genommen kann die Shell selbst gar keine Sockets bedienen außer Unix Domain, die im Dateisystem auftauchen.
Dazu nimmt man telnet oder auch netcat in die man Daten z.B. per Pipe übergeben kann.
Ich würde zu nc ("netcat") greifen. Beide Tools sind allerdings in so einem Szenario nicht ganz einfach, weil man ja normalerweise auf das Ergebnis reagieren will und dann entweder ständig neue Verbindungen aufmachen oder aber eine Instanz über zwei named pipes füttern bzw. auslesen muss. theinlein hast Du noch eine andere Idee?
Wenn du den Onkel Microcontroller gut kennst, und dessen Anfragen mittels Meldungen im ASCII bewerkstelligt werden können,
dann mache in einer Shell Commandline telnet ipadresse portnummer mal eine Verbindung auf und tippe den Request an den Controller per Hand ein (... wie gesagt, falls du das Bauen der Meldung per Zeicheneingabe hinbekommst) Wenn der MC antwortet, siehst du das in den ausgegebenen Zeilen.
Guter Ansatz! Bis später robert
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2505
|
Ich habe im Hinterkopf, dass Debian das immer deaktiviert hat, aber die Bash kann eigentlich schon rudimentär mit Sockets umgehen: | #!/bin/bash
exec 3<>/dev/tcp/heise.de/80
echo -ne 'GET / HTTP/1.0\n\n' >&3
cat <&3
exec 3>&-
|
Wäre das vielleicht eine Idee?
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
Vain schrieb: Ich habe im Hinterkopf, dass Debian das immer deaktiviert hat, aber die Bash kann eigentlich schon rudimentär mit Sockets umgehen: | #!/bin/bash
exec 3<>/dev/tcp/heise.de/80
echo -ne 'GET / HTTP/1.0\n\n' >&3
cat <&3
exec 3>&-
|
Wäre das vielleicht eine Idee?
Oh, das kannte ich noch nicht! Danke dafür! Ja, das sieht gut und handlebar aus. Ciao robert
|
mgolbs
(Themenstarter)
Anmeldungsdatum: 11. Januar 2009
Beiträge: 269
Wohnort: Tirschenreuth - Löbau
|
Hallo, danke für die vielen Hinweise. Ich werde das mal versuchen an meine Gegebenheiten anzupassen. In Python sieht der Kern eines Tests wie folgt aus: 1
2
3
4
5
6
7
8
9
10
11
12 | import socket
ip = raw_input("IP-Adresse: ")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, 50290))
nachricht = raw_input("getadc 1: ")
try:
for i in range(1, 100000, 1):
s.send(nachricht)
antwort = s.recv(1024)
finally:
s.close()
|
Wie wird das mit der Performance aussehen? In Python habe ich für AD Abfragen etwa 750Hz geschafft. Wenn ich das Verfahren telnet ipadresse portnummer nutzen würde und in eine Schleife füge, Daten des Controllers dann in eine Datei schreibe und danach sofort wieder Anfrage sende komme ich dann weit weg von 750Hz? | #!/bin/bash
exec 3<>/dev/tcp/heise.de/80
echo -ne 'GET / HTTP/1.0\n\n' >&3
cat <&3
exec 3>&-
|
Muss ich erst mal versuchen zu verstehen, bin leider kein Informatiker. Gruß und Dank Markus
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2505
|
mgolbs schrieb: [bash-snippet] Muss ich erst mal versuchen zu verstehen, bin leider kein Informatiker.
Okay, sorry, hier nochmal kommentiert: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | #!/bin/bash
# Öffne als Filedeskriptor Nummer 3 eine TCP-Verbindung zu heise.de auf
# Port 80. Das "<>" heißt, dass dieser Deskriptor zum Lesen und
# Schreiben benutzt werden kann (wie bei einem Socket).
exec 3<>/dev/tcp/heise.de/80
# Schicke einen einfachen HTTP-Request an heise. Die Umleitung ">&3"
# hinten heißt einfach, dass der String auf den eben geöffneten
# Deskriptor und damit auf das Socket geschrieben wird. Wichtig ist auch
# "-e" beim echo, denn das sorgt dafür, dass "\n" als Zeilenumbruch
# ausgewertet wird.
echo -ne 'GET / HTTP/1.0\n\n' >&3
# Lies von Deskriptor Nummer 3 bis es dort nichts mehr zu lesen gibt.
# Das holt die komplette Antwort vom Server ab.
cat <&3
# Schließt den Deskriptor wieder.
exec 3>&-
|
Die Bash behandelt Sockets genau wie reguläre Dateiumleitungen. Statt
„/dev/tcp/heise.de/80 “ hättest du also auch einen normalen Dateinamen
hinschreiben können. Wichtig ist aber: Dieses „/dev/tcp “ gibt es im
Dateisystem nicht, das ist rein virtuell und nur Bash-intern verfügbar. Das „echo “ und „cat “ sind also nur soetwas wie:
| echo hi >bla.txt
cat <bla.txt
|
Mit dem einzigen Unterschied, dass die Deskriptoren direkt über ihre
Nummer angesprochen werden. Aber das hast du bestimmt auch schonmal
gemacht, nämlich bei Befehlen wie:
Die Details des HTTP-Requests musst du nicht verstehen, das war nur ein
Beispiel. So könnte man halt mit einem reinen Bash-Skript eine Webseite
abrufen.
|
theinlein
Anmeldungsdatum: 29. Dezember 2007
Beiträge: 1279
|
... etwas anderes: du könntest mal schauen, ob auf deinen "alten Teilen" ein tcl drauf ist. tcl ist extrem schlank und für den Zaurus gab's das zumindest mal.
Einfach mal tclsh
aufrufen, ob's drauf ist.
|
mgolbs
(Themenstarter)
Anmeldungsdatum: 11. Januar 2009
Beiträge: 269
Wohnort: Tirschenreuth - Löbau
|
Hallo, danke fuer die Antworten. Bin gerade mit dem alten Psion Netbook Pro und Psion Linux hier im Netz. Mein erster Test bash Datei wie oben angelegt:
#!/bin/bash
# Öffne als Filedeskriptor Nummer 3 eine TCP-Verbindung zu heise.de auf
# Port 80. Das "<>" heißt, dass dieser Deskriptor zum Lesen und
# Schreiben benutzt werden kann (wie bei einem Socket).
exec 3<>/dev/tcp/heise.de/80
# Schicke einen einfachen HTTP-Request an heise. Die Umleitung ">&3"
# hinten heißt einfach, dass der String auf den eben geöffneten
# Deskriptor und damit auf das Socket geschrieben wird. Wichtig ist auch
# "-e" beim echo, denn das sorgt dafür, dass "\n" als Zeilenumbruch
# ausgewertet wird.
echo -ne 'GET / HTTP/1.0\n\n' >&3
# Lies von Deskriptor Nummer 3 bis es dort nichts mehr zu lesen gibt.
# Das holt die komplette Antwort vom Server ab.
cat <&3
# Schließt den Deskriptor wieder.
exec 3>&-
dabei bekam ich:
... 6: cannot create /dev/tcp/heise.de/80: directory nonexist tclsh ist auf dem Psionlinux nicht drauf. Ein ipkg install tcl83.ipk brachte zwar bei der Installation einen Fehler, tclsh laesst sich aber starten. Was koennte man da probieren? Ist tclsh sowas wie TCL/TK ohne Grafik? set server """"""IP-Mikrocontroller z.B. 192.168.0.90"""""""
set sockChan [socket $server """""Port Dienst Mikrocontroller z.B. 80"""""""]
gets $sockChan line
close $sockChan
puts " on $server is $line" Gruss und Dank Markus
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Wie hast Du das Skript gestartet, und welche Shell hat das Psion-Teil ? (ich hoffe, Du hast das Skript "ausführbar" gemacht und es dann mit ./meinskript ausgeführt ? Welche Bash dort läuft, verrät bash --version ) Außerdem: gibt es überhaupt den TCP-Dämon ? → which tcpd track
|
mgolbs
(Themenstarter)
Anmeldungsdatum: 11. Januar 2009
Beiträge: 269
Wohnort: Tirschenreuth - Löbau
|
Hallo, danke für die Meldung. Skript ist ausführbar, System hat busybox -damit geht wohl bash --version nicht? which tcpd meldet weder Fehler noch Auskunft. Das mit tclsh scheint ein guter Ansatz zu sein. Server über IP wird erkannt, Socket über Portnummer aufgebaut. Puts $... geht auch schon nur das gets $...wartet ewig. Eventuell ein \r\n Problem beim puts .... oder ... Gruß und Dank Markus
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Äh - busybox sagst Du ? Das ist eine absolut minimale Pseudo-Shell, die "all-in-one" nur das allernötigste an Bord hat. Also hier definitiv kein Ersatz für eine richtige Shell. Guckst Du mal bitte, ob nicht vielleicht doch noch eine richtige Shell vorhanden ist: which sh und which bash Wenn which tcpd nichts meldet, dann hat es einfach nichts gefunden. MaW: kein TCP-Dämon vorhanden. C'est ça. Jetzt müsste man nur noch herauskriegen, wie man TCP-Verbindungen unter busybox am geschicktesten öffnet. (aber das ist eine grundsätzlich andere Frage, als Du sie oben gestellt hattest !) track
|
mgolbs
(Themenstarter)
Anmeldungsdatum: 11. Januar 2009
Beiträge: 269
Wohnort: Tirschenreuth - Löbau
|
Hallo, danke für die Antwort. Unter which sh kommt /bin/sh und which bash nichts. Für das Kernanliegen habe ich was auf i386 Debian6/Ubuntu 10.04 prima funktioniert geschrieben: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | #!/usr/bin/tclsh
set line string;
puts "test"
set server 192.168.1.99;
set sockChan [socket $server 50290];
# set bu [fconfigure $sockChan -buffersize]
set x 0
while {$x < 10001} {
set x [expr {$x + 1}]
puts $sockChan "getadc 1 \r\n";
flush $sockChan;
gets $sockChan line;
puts $line;
# if {$x == 100} { set x 0 }
}
close $sockChan
|
Noch nicht auf Arm Psion Linux bzw. Sharp Zaurus Linux getestet, wird wohl funktionieren Dank Nachinstallation tclsh. Kern der Frage war ja ob man in einem Shell Skript Sockets handeln kann. Unter Systemen mit busybox wohl schwierig. Werde es mal auf einem normalen i386 bzw. amd64 Debian6 bzw. Ubuntu 10.04 probieren (wie oben beschrieben). Gruß und Dank Markus
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
mgolbs schrieb: danke für die Antwort. Unter which sh kommt /bin/sh ...
Dann könntest Du im Prinzip jederzeit eine "richtige" Posix-Shell starten mit dem Aufruf /bin/sh . Das Problem ist aber, dass der TCP-Dämon nicht läuft, und dem zufolge das Pseudogerät /dev/tcp/.... nicht existiert. Das musst Du erstmal klären, vorher wird das auf der Mini-Büchse nicht laufen ! Ob und wie das mit der tclsh geht, davon hab ich keine Ahnung. Das ist ein eigenes Kapitel. track
|
theinlein
Anmeldungsdatum: 29. Dezember 2007
Beiträge: 1279
|
"Was koennte man da probieren? Ist tclsh sowas wie TCL/TK ohne Grafik?" tclsh ist die "TCL-Shell" - also der reine TCL-Interpreter, der tcl-Programmiersprache spüricht. TK ist die Erweiterung mit grafischen Elementen. Nun, tcl ist die schlanke Alternive für die Socket-Programmierung. #! /bin/bash
# comment \
exec tclsh "$0" "$@"
set HOST localhost
set PORT 80
puts "versuche Verbindung zu $HOST auf Port $PORT aufzubauen"
set sock [socket $HOST $PORT]
puts "Verbindung steht" Dieses Shell-Script ruft sofort tclsh auf (die ersten 3 Zeilen, damit ist man unabhängig davon, wo tclsh installiert ist – aber: Bäcksläsch als letztes Zeichen am Zeilenende nicht vergessen). HOST und PORT sind Variablen, deren Inhalt du anpassen kannst, um deinen MC zu erreichen. Wenn der 'socket' Aufruf klappt, wird die Zeile "Verbindung steht" ausgegeben, anderenfalls wird mit einer Exception abgebrochen (jetzt mal Quick und Dirty). Wenn das bei deinen alten Geräten geht, dann können wir aus dem Python-Script einfach ein tcl-Script machen - oder?
|