Argumente mit Leerzeichen im Capture-Plugin
Argumente mit Leerzeichen im Capture-Plugin
Hi,
ist es möglich, Argumente mit Leerzeichen zu übergeben. Also z.B. wenn ich den Sendungsstring angebe und die Sendung heißt "Eine Sendung", dann ist
argv[1] = "Eine"
argv[2] = "Sendung"
im Programm. Ich hätte aber gerne
argv[1] = "Eine Sendung"
Wenn ich Anführungszeichen verwende, dann werden die Anführungszeichen tatsächlich mit übergeben, nicht wie auf der Shell dazu verwendet, die Leerzeichen zu gruppieren.
Danke.
Gruß,
Bernhard
ist es möglich, Argumente mit Leerzeichen zu übergeben. Also z.B. wenn ich den Sendungsstring angebe und die Sendung heißt "Eine Sendung", dann ist
argv[1] = "Eine"
argv[2] = "Sendung"
im Programm. Ich hätte aber gerne
argv[1] = "Eine Sendung"
Wenn ich Anführungszeichen verwende, dann werden die Anführungszeichen tatsächlich mit übergeben, nicht wie auf der Shell dazu verwendet, die Leerzeichen zu gruppieren.
Danke.
Gruß,
Bernhard
Also bei mir funktioniert es mit den Anführungszeichen, zumindest bei einer Batch-Datei. Du könntest höchstens noch \" anstelle des einfachen Anführungszeichen probieren.
"First they ignore you, then they ridicule you, then they fight you, then you win." - Mahatma Gandhi
Unterstütze die Weiterentwicklung von TV-Browser
Unterstütze die Weiterentwicklung von TV-Browser
Keine Änderung. Ich verwende allerdings Linux, nicht Windows. Als Test verwende ich schlicht und einfachds10 hat geschrieben:Also bei mir funktioniert es mit den Anführungszeichen, zumindest bei einer Batch-Datei. Du könntest höchstens noch " anstelle des einfachen Anführungszeichen probieren.
Code: Alles auswählen
#!/bin/sh
echo 1=$1
echo 2=$2
echo 3=$3
echo 4=$4
Mag sein, dass die Shell das so interpretiert, theoretisch sollte es aber korrekt übergeben werden. Wie das dann am Ende wirklich aussieht hängt tatsächlich vom Betriebssystem ab, da das Starten eines Prozesses von Java an das Betriebssystem delegiert wird. Möglicherweise würde ja ein anders Programm das auch anders auffassen.
"First they ignore you, then they ridicule you, then they fight you, then you win." - Mahatma Gandhi
Unterstütze die Weiterentwicklung von TV-Browser
Unterstütze die Weiterentwicklung von TV-Browser
Falsch. Ich habe mir den Code angeschaut.ds10 hat geschrieben:Mag sein, dass die Shell das so interpretiert, theoretisch sollte es aber korrekt übergeben werden. Wie das dann am Ende wirklich aussieht hängt tatsächlich vom Betriebssystem ab, da das Starten eines Prozesses von Java an das Betriebssystem delegiert wird. Möglicherweise würde ja ein anders Programm das auch anders auffassen.
Code: Alles auswählen
p = Runtime.getRuntime().exec((mData.getProgramPath() + " " + params).split(" "),
null, new File(path));
Argumente werden dabei der Reihe nach übergeben. Mit Shell müsste man
Code: Alles auswählen
p = Runtime.getRuntime().exec(new String[]{ "sh", "-c", mData.getProgramPath() +
" " + params }, null, new File(path));
Alternativ müsste man den Code erweitern damit der split()-Code die
Anführungszeichen behandelt. Mein Vorschlag (ebenfalls getestet):
Code: Alles auswählen
StringBuilder lastString = null;
ArrayList<String> args = new ArrayList<String>();
args.add(mData.getProgramPath());
for (String part : params.split(" ")) {
if (part.length() > 0 && part.charAt(0) == '"') {
if (part.charAt(part.length()-1) == '"')
args.add(part);
else {
lastString = new StringBuilder(part);
lastString.deleteCharAt(0);
}
} else if (lastString != null) {
lastString.append(' ');
lastString.append(part);
if (part.charAt(part.length()-1) == '"') {
lastString.deleteCharAt(lastString.length() - 1);
args.add(lastString.toString());
lastString = null;
}
} else {
args.add(part);
}
}
p = Runtime.getRuntime().exec(args.toArray(new String[0]), null, new File(path));
Gruß,
Bernhard
Naja, dass execve() verwendet wird, hängt von Java ab, und nicht vomds10 hat geschrieben:Nix falsch, es ist genau wie ich geschrieben habe, das Ausführen wird an das Betriebssystem delegiert, wenn Linux dann eben execve ausführt, dann ist dass eben so.bwalle hat geschrieben:Falsch. Ich habe mir den Code angeschaut.ds10 hat geschrieben:Mag sein, dass die Shell das so interpretiert, theoretisch sollte es aber korrekt übergeben werden. Wie das dann am Ende wirklich aussieht hängt tatsächlich vom Betriebssystem ab, da das Starten eines Prozesses von Java an das Betriebssystem delegiert wird. Möglicherweise würde ja ein anders Programm das auch anders auffassen.
Code: Alles auswählen
p = Runtime.getRuntime().exec((mData.getProgramPath() + " " + params).split(" "), null, new File(path));
Betriebssystem. Aber ich halte das auch für das erwartete Verhalten wenn man
die Array-Version verwendet.
Der "Spezialfall" für Linux würde praktisch auf jedem Desktopsystem außerds10 hat geschrieben: Das glaube ich dir auch sofort, dass es so geht (da die Parameter alle zusammen weitergereicht werden), aber ein Spezialfall für Linux werden wir sicher nicht einbauen.
Windows funktionieren.
Wenn dem so ist (keine Ahnung, ich habe kein Windows), dann ist aber diebwalle hat geschrieben:Alternativ müsste man den Code erweitern damit der split()-Code die
Anführungszeichen behandelt. Mein Vorschlag (ebenfalls getestet):
Ist allerdings unter Windows dann wieder nicht korrekt, dort habe ich nämlich aufgrund von WinTVCap_GUI viele Erfahrungen mit dem richtigen Starten von Programmen gemacht und dort funktioniert es nur mit dem kompletten split richtig.Code: Alles auswählen
StringBuilder lastString = null; ArrayList<String> args = new ArrayList<String>(); args.add(mData.getProgramPath()); for (String part : params.split(" ")) { if (part.length() > 0 && part.charAt(0) == '"') { if (part.charAt(part.length()-1) == '"') args.add(part); else { lastString = new StringBuilder(part); lastString.deleteCharAt(0); } } else if (lastString != null) { lastString.append(' '); lastString.append(part); if (part.charAt(part.length()-1) == '"') { lastString.deleteCharAt(lastString.length() - 1); args.add(lastString.toString()); lastString = null; } } else { args.add(part); } } p = Runtime.getRuntime().exec(args.toArray(new String[0]), null, new File(path));
Array-Version der exec()-Methode kaputt. Wenn Java meint, unter Windows eine
Shell verwenden zu müssen, dann muss es selber das richtige Escaping machen.
Ihr habt nicht zufällig vergessen, die Anführungszeichen selbst dann zuEine zusätzliche Beachtung von Anführungszeichen hat unter Windows Problem
verursacht (welche weiß ich auch nicht mehr, ist schon einige Zeit her, ich
weiß nur noch, dass dann einige Programme damit nicht klar kamen). Man könnte
sonst auch einfach eine andere exec-Methode benutzen, die das Splitten selbst
macht, dann bräuchte man das nicht extra einprogrammieren.
entfernen nachdem der Split durchgeführt wurde?
Die normale exec()-Methode zu verwenden, also mit Strings, bringt hier auch
nichts, da die auch nur auf Spaces (und Newlines, Tabs, etc.) matched.
Die sauberste Methode wäre m.E. keinen großen String zur Übergabe der
Argumente zu verwenden sondern eine Liste. Dann kann der Anwender schon nach
1., 2., 3., usw. Argument trennen und man braucht kein Escaping verwenden.
Dazu noch jeweils eine Checkbox, ob ein leerer String übergeben werden soll,
wenn das ganze zu einem leeren String evaluiert, oder ob dann die Liste
um eins verschoben werden soll.
Aber dein Text klingt für mich jetzt als ob es nur wichtig wäre, dass es unter
Windows funktioniert.
Nicht ihr, wenn dann ich (WinTVCap_GUI habe ich allein geschrieben, wenn also hier einer keine Ahnung hat, dann bin ich das), aber wie ich ja sagte, weiß ich nicht mehr, wo das Problem war, da ich mir wirklich nicht jede Kleinigkeit merken kann.bwalle hat geschrieben:Ihr habt nicht zufällig vergessen, die Anführungszeichen selbst dann zu
entfernen nachdem der Split durchgeführt wurde?
Da stimme ich dir zu, nur ist das für einen Durchschnittsuser viel zu kompliziert, selbst mit dem jetzigen System haben schon genug Leute Schwierigkeiten.bwalle hat geschrieben:Die sauberste Methode wäre m.E. keinen großen String zur Übergabe der
Argumente zu verwenden sondern eine Liste. Dann kann der Anwender schon nach
1., 2., 3., usw. Argument trennen und man braucht kein Escaping verwenden.
Dazu noch jeweils eine Checkbox, ob ein leerer String übergeben werden soll,
wenn das ganze zu einem leeren String evaluiert, oder ob dann die Liste
um eins verschoben werden soll.
Nein, ich fände es auch gut, wenn es unter Linux problemlos laufen würde. Aber wenn ich allein die Wahl hätte, wäre es mir tatsächlich wichtiger, dass es unter Windows richtig funktioniert, aus rein supporttechnischen Gründen:bwalle hat geschrieben:Aber dein Text klingt für mich jetzt als ob es nur wichtig wäre, dass es unter
Windows funktioniert.
https://sourceforge.net/project/showfil ... _id=495879
Linux Benutzer kennen sich im Allgemeinen viel besser mit ihrem System aus und sind daher eher in der Lage mit solchen Problemen umzugehen.
"First they ignore you, then they ridicule you, then they fight you, then you win." - Mahatma Gandhi
Unterstütze die Weiterentwicklung von TV-Browser
Unterstütze die Weiterentwicklung von TV-Browser
Ehrlich gesagt finde ich das jetzige System für den Durchschnittsuserds10 hat geschrieben:Da stimme ich dir zu, nur ist das für einen Durchschnittsuser viel zu kompliziert, selbst mit dem jetzigen System haben schob genug Leute Schwierigkeiten.bwalle hat geschrieben:Die sauberste Methode wäre m.E. keinen großen String zur Übergabe der
Argumente zu verwenden sondern eine Liste. Dann kann der Anwender schon nach
1., 2., 3., usw. Argument trennen und man braucht kein Escaping verwenden.
Dazu noch jeweils eine Checkbox, ob ein leerer String übergeben werden soll,
wenn das ganze zu einem leeren String evaluiert, oder ob dann die Liste
um eins verschoben werden soll.
komplizierter, da der an bestimmten Stellen Anführungszeichen setzen muss.
Das zählt bei mir als Argument nicht. Ich sag ja nicht dass du dieNein, ich fände es auch gut, wenn es unter Linux problemlos laufen würde. Aber wenn ich allein die Wahl hätte, wäre es mir tatsächlich wichtiger, dass es unter Windows richtig funktioniert, aus rein supporttechnischen Gründen:bwalle hat geschrieben:Aber dein Text klingt für mich jetzt als ob es nur wichtig wäre, dass es unter
Windows funktioniert.
https://sourceforge.net/project/showfil ... _id=495879
Windows-Version kaputt machen sollst sondern die Linuxversion fixen.
Ich bin mir auch ziemlich sicher dass MacOS X das gleiche Problem hat.
Linux Benutzer kennen sich im Allgemeinen viel besser mit ihrem System aus und sind daher eher in der Lage mit solchen Problemen umzugehen.
Es gibt keine Möglichkeit, mit dem Problem umzugehen, außer keine Leerzeichen
zu verwenden, was bei Titeln nicht unbedingt die schönste Lösung ist.
Linuxprogramme verwenden i.d.R. getopt() oder getopt_long() zum Parsen
von Argumenten. Diese Funktion geht davon aus, dass die Argumente richtig
sind. Die richtige Übergabe ist Aufgabe der Shell.
Also das Argument lasse ich jetzt nicht gelten. Du kannst ja sogar programmieren, also wäre es für dich ein leichtest ein Plugin zu basteln, was richtig funktioniert.bwalle hat geschrieben:Es gibt keine Möglichkeit, mit dem Problem umzugehen, außer keine Leerzeichen
zu verwenden, was bei Titeln nicht unbedingt die schönste Lösung ist.
(Das CapturePlugin bietet ja auch noch die Möglichkeit die clean-Funktion zu verwenden um alle Sonderzeichen aus dem übergebenen String zu entfernen, Leerzeichen werden dann zum Unterstrich.)
Das CapturePlugin müsste an der Stelle sowieso mal auf ProcessBuilder umgestellt werden, da das ja jetzt die empfohlene Startweise für externe Prozesse ist.
"First they ignore you, then they ridicule you, then they fight you, then you win." - Mahatma Gandhi
Unterstütze die Weiterentwicklung von TV-Browser
Unterstütze die Weiterentwicklung von TV-Browser
Das Problem ist mir jetzt übrigens doch wieder eingefallen. Das Aufnahmeprogramm WinTVCap.exe erwartet alle Kommandos einer Kommandozeile als einzelne Tokens, wenn man dort einen Teil der Kommandos als Ganzes übergibt (also so wie in deinem Codeabschnitt mit sh), funktioniert die Aufnahme nicht. Das ließ sich nur durch das split beheben, alle anderen Programme hatten danach keine Probleme mit Anführungszeichen zusammengesetzte Tokens als solche zu erkennen. Unter Windows muss die Methode also irgendwie anders funktionieren.
"First they ignore you, then they ridicule you, then they fight you, then you win." - Mahatma Gandhi
Unterstütze die Weiterentwicklung von TV-Browser
Unterstütze die Weiterentwicklung von TV-Browser
Klar kann ich die Quellen verändern (oder kopieren umbenennen, und dannds10 hat geschrieben:Also das Argument lasse ich jetzt nicht gelten. Du kannst ja sogar programmieren, also wäre es für dich ein leichtest ein Plugin zu basteln, was richtig funktioniert.bwalle hat geschrieben:Es gibt keine Möglichkeit, mit dem Problem umzugehen, außer keine Leerzeichen
zu verwenden, was bei Titeln nicht unbedingt die schönste Lösung ist.
verändern). Das verstehe ich aber
nicht unter "umgehen", sondern "patchen".
Richtig, und das mache ich zur Zeit. Das verstehe ich allerdings unter "keine(Das CapturePlugin bietet ja auch noch die Möglichkeit die clean-Funktion zu
verwenden um alle Sonderzeichen aus dem übergebenen String zu entfernen,
Leerzeichen werden dann zum Unterstrich.)
Leerzeichen verwenden".
Ändert hier nichts am Verhalten. Nur dass es keine Version mehr gibt, die nurDas CapturePlugin müsste an der Stelle sowieso mal auf ProcessBuilder
umgestellt werden, da das ja jetzt die empfohlene Startweise für externe
Prozesse ist.
aus einem String besteht.
Ja. Ich hab jetzt mal Windows ausgekramt. Folgender Codeds10 hat geschrieben:Das Problem ist mir jetzt übrigens doch wieder eingefallen. Das Aufnahmeprogramm WinTVCap.exe erwartet alle Kommandos einer Kommandozeile als einzelne Tokens, wenn man dort einen Teil der Kommandos als Ganzes übergibt (also so wie in deinem Codeabschnitt mit sh), funktioniert die Aufnahme nicht. Das ließ sich nur durch das split beheben, alle anderen Programme hatten danach keine Probleme mit Anführungszeichen zusammengesetzte Tokens als solche zu erkennen. Unter Windows muss die Methode also irgendwie anders funktionieren.
Code: Alles auswählen
Process p = Runtime.getRuntime().exec(
new String[]{ "show_args",
""1", "2"" } );
Code: Alles auswählen
argv[1] = 1 2
Code: Alles auswählen
argv[1] = "1
argv[2] = 2"
Allerdings funktioniert das ganze mit
Code: Alles auswählen
Process p = Runtime.getRuntime().exec(
new String[]{ "show_args",
"1 mit vielen Leerzeichen", "2" } );
Außerdem habe ich festgestellt dass sich
unter Windows nicht ausführen lässt, also eine Exception wirft. IMO ein weiterer Bug (von Java).
Code: Alles auswählen
String[]{ "\"1 mit Leerzeichen", "2\"" }
Ja, kann gut sein, dass dies ein Bug in Java ist.bwalle hat geschrieben:Ja. Ich hab jetzt mal Windows ausgekramt. Folgender Code
liefert unter Windows:Code: Alles auswählen
Process p = Runtime.getRuntime().exec( new String[]{ "show_args", ""1", "2"" } );
und unter LinuxCode: Alles auswählen
argv[1] = 1 2
Also wenn du mich fragst ist das ein Bug von Java unter Windows. Unter Linux bekommt das aufgerufene Programm exakt die Strings, die man ihm von Java übergibt. Unter Windows wird eine Shell aufgerufen und die Anführungszeichen werden weggestrippt.Code: Alles auswählen
argv[1] = "1 argv[2] = 2"
Genau, der Eintrag mit den vielen Leerzeichen würde alle Programme, die die Tokens einzeln erwarten aus dem Tritt bringen.bwalle hat geschrieben:Allerdings funktioniert das ganze mit
auch unter Windows korrekt. Damit kann dann WinTVCap.exe nicht umgehen, wenn ich dich richtig verstanden habe.Code: Alles auswählen
Process p = Runtime.getRuntime().exec( new String[]{ "show_args", "1 mit vielen Leerzeichen", "2" } );
Es ist auf jeden Fall ziemlich unerwartet, dass sich ein und dieselbe Methode auf den unterschiedlichen BS komplett anders verhält.
"First they ignore you, then they ridicule you, then they fight you, then you win." - Mahatma Gandhi
Unterstütze die Weiterentwicklung von TV-Browser
Unterstütze die Weiterentwicklung von TV-Browser
Und welche Programme sind das? Vor allem verstehe ich den Sinn immer noch nicht. Erwartet deine Anwendung quasiGenau, der Eintrag mit den vielen Leerzeichen würde alle Programme, die die Tokens einzeln erwarten aus dem Tritt bringen.ds10 hat geschrieben: auch unter Windows korrekt. Damit kann dann WinTVCap.exe nicht umgehen, wenn ich dich richtig verstanden habe.
Code: Alles auswählen
argv[1] = ein
argv[2] = ganz
argv[3] = langer
argv[4] = String
Code: Alles auswählen
argv[1] = "ein
argv[2] = ganz
argv[3] = langer
argv[4] = String"