• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Was gibt es Schöneres als den Mai draußen in der Natur mit allen Sinnen zu genießen? Lasst uns teilhaben an Euren Erlebnissen und macht mit beim Thema des Monats Da blüht uns was! ---> Klick

Socket lesen/schreiben mit Shell Script

olnol

Alkmene
Registriert
28.12.09
Beiträge
30
Hallo zusammen. Folgende Konstellation: Ich habe in Parallels DD-WRT installiert und den 2.COM-Port dieser VM auf Socket-File "/tmp/vm", Server eingestellt. Nun möchte ich gerne aus Mac OS X mit der VM über diesen Socket kommunizieren. Über eine Telnet-Verbindung im Terminal mittels telnet /tmp/cm kommt eine Verbindung zustande und es können Daten übertragen werden.

Doch geht es auch ohne eine telnet Verbindung?
Gebe ich echo "irgendwas" 1>&/tmp/vm im terminal ein bekomme ich die Fehlermeldung "Operation not supportet on socket".

Das ganze dient im Moment nur zu Simulationszwecken und als Entwicklungsumgebung. Später soll auf einem Router auf dem DD-WRT läuft ein Shell-CGI-Skript über eine Socket-Verbindung Daten zwischen anderen Programmen austauschen.

Ich hoffe mir kann jemand weiterhelfen!
Danke
 

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Hi,

die Socketkommunikation aus einem Shellscript heraus ist normalerweise kein Problem. Allerdings hast du da einen Tippfehler, es müsste

echo "bleh" > /tmp/vm
heißen.

Das "1>&" nimmt alles nach STDOUT und ist nicht unbedingt gewünscht.

Wenn Virtual Box oder ähnliche Systeme einen COM-Port umbiegen, dann sollte man den u.U. auch so behandeln, sprich mit setserial evtl. Geschwindigkeit usw. einstellen. Könnte u.U. notwendig sein.

Was du noch machen kannst um _ALLEN_ Output umzubiegen wäre ein "&>", e.g.:

echo "bleh" &> /tmp/vm
das würde dir stdout und stderr nach /tmp/vm umbiegen.

Ansonsten gibt es, sofern es beim Build der Bash aktiviert wurde, noch die Möglichkeit via Networksockets zu arbeiten.

Als Beispiel:
echo "bleh" > /dev/tcp/1.2.3.4/80
würde auf Server 1.2.3.4 auf Port 80 eine TCP Verbindung herstellen und dann dort "bleh" abladen und anschließend die Verbindung wieder trennen. Da das allerdings allgemein als Sicherheitsproblem angesehen wird, ist es meistens nicht aktiviert.

Für sowas nimmt man dann "netcat" (nc).

Wenn du einfach mal Sockets testen möchtest, kannst du mit mkfifo selber sockets erstellen:

Terminal 1:
$ mkfifo /tmp/testfifo
$ cat /tmp/testfifo
Terminal 2:
$ echo "bleh" > /tmp/testfifo
Terminal 1:
$ mkfifo /tmp/testfifo
$ cat /tmp/testfifo
bleh
$
cu
 

olnol

Alkmene
Registriert
28.12.09
Beiträge
30
Danke zunächst für die ausführliche Antwort.

Also sowohl Beispiel 1 als auch 2 funktioniert nicht. Es erscheint wieder die Meldung : -bash: /tmp/vm: Operation not supported on socket.

Das letzte Beispiel funktioniert, ich kann Daten von einem ins andere Terminal senden.

Die Sache mit den Netzwerksockets ist bei DD-WRT scheinbar deaktiviert, zumindest finde ich unter /dev kein tcp.
Oder muss dieses Verzeichnis manuell erstellt werden?
Wie würde ich dann über die Shell ein Netzwerksocket generieren?
 

olnol

Alkmene
Registriert
28.12.09
Beiträge
30
Nun. Ich bin ein Stück weiter gekommen. Ich kann nun mittels netcat "nc" eine TCP-Socket Verbindung zwischen meinem Mac und Parallels(DD-WRT) herstellen. Auch eine Verbindung zwischen zwei Terminals auf meinem Mac, dh ohne Parallels, funktioniert. Also quasi als Chat. Aber dazu nun mehr: Ein C-Programm soll nun mit einem Shell-Skript kommunizieren können (beide laufen auf dem Mac).

Dazu habe ich folgendes gemacht

Terminal 1
Code:
 nc -l Port | ./Pfad zum C-Prog
Terminal 2
Code:
 echo "23" | nc Ip Port
C-Prog
Code:
int main(void) {
    int fu;
    scanf("%d",&fu);
    printf("%d\n",fu+1);
    printf("Das war mein Prog\n");
}
Terminal1
Code:
24
Das war mein Prog
Dh, die unidirektionale Verbindung vom Shell-Skript -> C-Prog funktioniert. Allerdings soll eine bidirektionale Verbindung möglich sein. Das ganze dient im mom nur zu Testzwecken. Später soll dann ein Cgi-Shell-Skript was auf einem Router mit DD-WRT läuft Daten mit einem C-Prog, was ebenfalls auf dem Router läuft, mittels TCP-Socket austauschen können.

Wie lässt sich daher eine bidirektionale Verbindung realisieren?
 

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Hi,

du solltest dir unbedingt mal die inetd packages anschauen. Es gibt da verschiedene Varianten - jede natürlich die Beste ;) - aber die könnten dich wirklich weiterbringen.

Ein inetd lauscht auf einem bestimmten Port und bei einer Verbindung startet er dein Programm und leitet alles Empfangene auf stdin deines Programms um. Um was zu versenden schreibst du einfach was nach stdout und der inetd schickt es über die Verbindung nach außen. Wird die Verbindung getrennt, killt er dein Programm. Killst du dein Programm beendet er die Verbindung :)

Diese Teile sparen dir viel Arbeit. Kein forken, kein Sockethandling :)

Warum die Verbindung auf den Socket von Parallels nicht funktioniert ist mir allerdings ein Rätsel. Wenn Telnet geht, müsste alles andere auch gehen, es sei denn Telnet initialisiert da irgendwas.

Die Devices /dev/tcp und /dev/udp sieht man in der Bash nicht. Genauso wenig wie /dev/stderr /dev/stdin und /dev/stdout, auch wenn man sie benutzen kann:

#!/bin/bash
cat /dev/stdin | while read line; do echo $line; done
cu
 

olnol

Alkmene
Registriert
28.12.09
Beiträge
30
Dh ich komme mit netcat nicht weiter?
Habe dbzgl noch folgendes gefunden:

Bildschirmfoto 2010-04-21 um 18.50.22.png

Nur weiß ich nicht so recht was nach dem Eingeben des letzten Kommandos passieren muss und ob das gernerell meinem Vorhaben entspricht. Rein dem Bild nach zu urteilen würde ich sagen ja. Ich schicke eine Ausgabe von A nach B. Und eine Ausgabe von B wird durch die backpipe an A gesendet. Entspricht das nicht CGI-Shell-Skript <-> C-Prog ??

Auch das hier ist mir noch untergekommen.
Gefunden hier:http://www.netzmafia.de/skripten/server/server2.html

Aufruf als Server

Durch den Aufruf PROGRAM | nc -l -p PORT -w TIMEOUT
oder nc -l -p PORT -w TIMEOUT | PROGRAM

  1. erwartet netcat genau eine Verbindung auf Port PORT,
  2. verbindet netcat diese mit der Aus- oder Eingabe von PROGRAM und
  3. wartet maximal TIMEOUT Sekunden darauf, daß die Verbindung abgebrochen wird.
Soll der Port bidirektional sein (Ein- und Ausgabe), lautet der Aufruf: nc -l -p PORT -e PROGRAM
Der Befehl nc -l -p PORT -e PROGRAM, wobei PROGRAM ein ausführbares Shell-Skript ist funktioniert allerdings nicht. Sobalt ich den Client in einem zweiten Terminal starte wird die Verbindung direkt beendet. In dem Shell-Skript lese von stdin und gebe den Inhalt+1 aus. Heißt das nicht das die Ausgabe die das PROGRAM tätigt an den Client gesendet wird. Und die Daten die der Client sendet vom PROGRAM auf stdin gelesen werden können? Also genau das was ich will?
 
Zuletzt bearbeitet:

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Hallo,

die Netcat lösung ist Gebastel. Netcat benutze ich persönlich um tarballs durchs netz zuschieben, oder um andere Dinge zu testen (Durchlässigkeit von Firewalls o.ä.) aber nicht im produktiven (Server)-Betrieb.

Ein inetd sollte für dich genau das richtige sein. Hardened code der mit hosts.allow/hosts.deny filtern und anderen Dingen arbeitet und deinen Prozess in der vorbestimmten Umgebung startet und kontrolliert sowie für die korrekte Abwicklung des Datenverkehrs sorgt.

Zusammen mit stunnel sogar verschlüsselt wenns sein muss.

Diese Netcat-Variante ist zwar mal ganz nett, bringt aber nix

Wenn du wie oben beschrieben sowohl den Server als auch den Client startest, hast du das Problem das nach dem Senden der letzten Daten (sofern welche vorhanden sind), die Verbindung direkt beendet wird.

Das backpipe Prinzip ist dann noch mehr gebastel. Netcat ist nicht dafür gemacht die Daten in beide Richtungen zu nutzen. Aus diesem Grund wird eine zweite Verbindung initiiert über welche die Daten zurück geschickt werden. Besser wäre es allerdings die Daten nur über eine Verbindung laufen zu lassen.

Wie schon geschrieben benutze inetd bzw. eine seiner Varianten: xinetd.

cu
 

MacMark

Jakob Lebel
Registriert
01.01.05
Beiträge
4.874
… Wie lässt sich daher eine bidirektionale Verbindung realisieren?

Miami:~ macmark$ nc -lk 9999
hallo aus Miami
hey! hier KeyWest
da bin ich wieder

KeyWest:~ macmark$ nc Miami.local 9999
hallo aus Miami
hey! hier KeyWest
^C
KeyWest:~ macmark$ nc Miami.local 9999
da bin ich wieder

Ein Chat zwischen zwei Rechnern. Auch wenn der Client abbricht, kann er wieder neu kontakten, da der Server weiter lauscht.
 

olnol

Alkmene
Registriert
28.12.09
Beiträge
30
Ok. Danke. Ich starte nochmal einen Versuch mit netcat.
Folgende Konstellation wird benötigt:

Netcat Server A (stdout) ----> (stdin) Prog (stdout) -----> (stdin) Netcat Server Port B

Dies hab ich folgendermaßen implementiert:
nc -l 3000|prog|nc -l 4000
Das Prog liest lediglich von stdin und gibt etwas auf stdout aus.
Ich möchte also über den Client Port 3000 dem Prog etwas senden, und auf dem Client Port 4000 die Ausgabe des Progs empfangen.