Hallo Wissende,
gegeben sei ein Kommandozeilenprogramm unter Linux, das ein Argument erwartet, welches das Programm als Namen seiner Eingabedatei interpretiert. Ich möchte das Programm aber von einem anderen Programm aus aufrufen, und würde ihm seine Eingabedaten lieber via Pipe übergeben. Gibt es eine Möglichkeit, das zu erreichen, ohne auf temporäre Dateien auszuweichen? Einige Programme lesen von STDIN, wenn der Dateiname „-“ ist (z.B. vim), aber das scheint hier nicht zu funktionieren. Irgendwelche Ideen?
Gruß
Chondron
Hallo Chondron,
gegeben sei ein Kommandozeilenprogramm unter Linux, das ein
Argument erwartet, welches das Programm als Namen seiner
Eingabedatei interpretiert. Ich möchte das Programm aber von
einem anderen Programm aus aufrufen, und würde ihm seine
Eingabedaten lieber via Pipe übergeben.
Sind da der „Dateiname“ und die „Eingabedaten“ das gleiche?
Das heisst, Du möchtest ihm den Namen der Eingabedatei übergeben? Mit
befehl1 | befehl2
liest befehl2 von der Standardausgabe des befehls1
http://www.trampelwurm.ch/schmidt/wilhelmtux/swissre…
dort und anderswo unter dem Begriff „pipe“
Allerdings müsstest Du schon etwas präziser werden, welcher Befehl welches Argument erwartet. Wenn dein Befehl das Argument z.B. nur so erwartet
befehl -d dateiname
dann ist eine Pipe nicht geeignet.
Eine andere Möglichkeit wäre eventuell die Kommandosubstitution mittels $( befehl )
http://de.linwiki.org/wiki/Linuxfibel_-_Shells_-_Bas…
das scheint hier nicht zu
funktionieren.
Warum? Gibt es einene Fehlermeldung (welche?) oder passiert nichts? Du müsstest also genauer schreiben, wie dein erster Befehl sein Argument erwartet und wie der zweite Befehl das Argument ausgibt.
Viele Grüße
Marvin
Hallo Marvin,
also, konkret: das Programm ist flasm. Aufruf funktioniert wie folgt:
Usage: flasm [command] filename
Commands:
-d Disassemble SWF file to the console
[...]
Ich hätte jetzt aber gerne, dass die Daten nicht aus
filename
sondern von STDIN gelesen werden, sodass ich keine temporäre Datei brauche.
Gruß
Chondron
Hallo Chondron,
das Programm ist flasm. Aufruf funktioniert wie
folgt:
flasm [command] filename
Ich hätte jetzt aber gerne, dass die Daten nicht aus
filename
sondern von STDIN gelesen werden, sodass ich keine temporäre
Datei brauche.
Hm, ich bin etwas schwer von Begriff und sehe die temporäre Datei noch nicht. Du hast eine swf-Datei, sagen wir foo.swf und willst sie disassemblieren. Also gibst Du
flasm foo.swf
ein und fertig. Oder erzeugst Du foo.swf erst mit einem anderen Programm? Sagen wir mal das Programm bar erzeugt die Datei foo.swf, die dann wiederum durch flasm gedreht werden soll? Du siehst, ich durchschaue den Ablauf noch nicht so recht 
Da aber flasm nicht von Standard-In lesen kann (ich habe es nicht da, aber in der Manpage steht zumindest nichts davon), so erschlägt man das meist mit einem Miniskript, etwa so:
DATEI="foo.swf"
bar ${DATEI} && flasm ${DATEI}
wobei man die Variable DATEI eigentlich lieber als Parameter übergeben sollte. Für das imaginäre Programm bar habe ich jetzt einfach angenommen, daß es den Namen der zu erzeugenden Datei auch als Parameter empfängt. Die Verkettung mit && bewirkt, daß flasm nur ausgeführt wird, wenn zuvor bar erfolgreich war, also tatsächlich die Datei foo.swf erzeugt hat.
Bisschen viel Annahmen, aber vielleicht kannst Du mir noch etwas mehr über den bisher unbekannten ersten Befehl sagen.
Viele Grüße
Marvin
Hallo Marvin,
sorry dass ich Verwirrung stifte, also hier mal der Kontext der Geschichte:
Ich entwickle ein Programm, das in Flash-Dateien enthaltene Links (URLs) analysieren muss. Zu diesem Zweck muss man die URLs natürlich zunächst extrahieren.
Was ich habe ist der Inhalt einer SWF-Datei, der in einer Variablen meines Programms gespeichert ist (Die Datei selbst habe ich aber nicht, die empfange ich übers Netzwerk). Die Daten möchte ich jetzt durch flasm jagen und den Output nach den besagten URLs durchsuchen. Jetzt könnte man natürlich einfach hingehen, die SWF-Daten auf die Platte schreiben, flasm auf die Datei loslassen, den Output wieder einsammeln und die temporäre Datei löschen. Aus verschiedenen Gründen, nicht zuletzt Performanz, möchte ich eine solche Lösung aber vermeiden. Daher wäre es schön, wenn ich flasm die Daten auf STDIN schicken könnte.
Alle Klarheiten beseitigt? 
Gruß
Chondron
Hallo Chondron,
Alle Klarheiten beseitigt? 
Joo! 
Aber da flasm, soweit ich das sehe, keine Eingaben von stdin erwartet (was ungewöhnlich für Linux-Programme ist), weder mit Pipe noch mit Umlenkung, also _, sehe ich hier keine Chance.
Die Performance liesse sich erhöhen, wenn Du die Datei im RAM ablegst, wenn das denn möglich ist.
Tut mir leid, aber vielleicht fällt ja jemand anderem was ein…
Viele Grüße
Marvin_
Hallo Chondron,
ich habe mir mal den Quelltext von flasm angeschaut (http://www.nowrap.de/download/flasm16src.zip von http://www.nowrap.de/flasm.html), danach ist eine Unterstützung von der Standardeingabe nicht enthalten. Diese lässt sich aber leicht nachrüsten:
In der Datei flasm.c vor der Zeile 1732 die Zeilen
if (strcmp(inputName, "stdin") == 0)
inputFile = stdin;
else
einfügen. Dann sieht der Block so aus:
if (inputName == NULL)
usage();
if (strcmp(inputName, "stdin") == 0)
inputFile = stdin;
else
if ((inputFile = fopen(inputName, "rb")) == NULL)
tellUser(1, "Couldn't open input file %s for reading", inputName);
}
int main(int argc, char \*argv[])
Wenn Du nun (nach dem Kompilieren) als Dateinamen ‚stdin‘ angibst, dann wird die Standardeingabe verwendet.
Getestet habe ich dies mit
wget -q -O - http://cache.addthis.com/downloads/demo/flash/latest/helloworld\_icons.swf | ./flasm -d stdin
Gruß
Diether
Hallo Diether,
wow, hätte nicht erwartet, dass da gleich ein kompletter Patch zurückkommt. Vielen Dank!
Gruß
Chondron
Hi,
als Alternative zu der Patch-Lösung: Die Datei-Deskriptoren der Prozesse sind im virtuellen proc-Dateisystem verfügbar. Also kannst du so etwas machen:
... | foo /proc/self/fd/0
Ich weiß momentan nicht, wie weit Folgendes standardisiert ist, aber normalerweise gibt es dafür auch eine praktische Abkürzung:
... | foo /dev/stdin
Beides setzt natürlich voraus, dass der Befehl foo überhaupt auf einem Stream arbeiten kann (und nicht z.B. in der Datei herumspringen will).
Viele Grüße
Andreas