Wie würde ich eine .sh-Datei mit NSTask ausführen und seine Ausgabe bekommen?
-
30-09-2019 - |
Frage
Ich brauche eine .sh-Datei ausführen und seine Ausgabe zu erhalten. Ich brauche die Einrichtung der Datei als auch zu sehen.
Die .sh Datei einfach läuft eine Java-Anwendung über den Anschluss.
Irgendwelche Ideen? Ich bin wirklich auf diese stecken .....
Elias
Die server.sh-Datei:
echo Starting Jarvis Program D.
ALICE_HOME=.
SERVLET_LIB=lib/servlet.jar
ALICE_LIB=lib/aliceserver.jar
JS_LIB=lib/js.jar
# Set SQL_LIB to the location of your database driver.
SQL_LIB=lib/mysql_comp.jar
# These are for Jetty; you will want to change these if you are using a different http server.
HTTP_SERVER_LIBS=lib/org.mortbay.jetty.jar
PROGRAMD_CLASSPATH=$SERVLET_LIB:$ALICE_LIB:$JS_LIB:$SQL_LIB:$HTTP_SERVER_LIBS
java -classpath $PROGRAMD_CLASSPATH -Xms64m -Xmx128m org.alicebot.server.net.AliceServer $1
Mein aktueller Code:
NSTask *server = [NSTask new];
[server setLaunchPath:@"/bin/sh"];
[server setArguments:[NSArray arrayWithObject:@"/applications/jarvis/brain/server.sh"]];
NSPipe *outputPipe = [NSPipe pipe];
[server setStandardInput:[NSPipe pipe]];
[server setStandardOutput:outputPipe];
[server launch];
NSMutableString *outputString = [NSMutableString string];
while ([outputString rangeOfString:@"Jarvis>"].location == NSNotFound) {
[outputString appendString:[[[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding] autorelease]];
NSRunAlertPanel(@"", outputString, @"", @"", @"");
}
Die NSRunAlertPanel ist nur für die Ausgabe zu überprüfen. Nun ist mein Code friert und nicht einmal auf die alertpanel bekommen.
Lösung
Siehe Antwort auf diese Frage .
Es gibt ein paar Dinge, die in Ihrem Skript festgelegt werden sollten:
- Das Skript mit einem beginnen soll shebang. Achten Sie außerdem darauf, dass die Skript hat seine ausführbare Bit gesetzt.
- Da die Umgebungsvariablen gesetzt sind, bezogen auf das Shell-Skript-Verzeichnis auf, müssen Sie sicherstellen, dass das Skript Verzeichnis das aktuelle Verzeichnis.
- Sie müssen die Umgebungsvariablen exportieren, die mit dem Java-Prozess sichtbar sein soll.
- In der letzten Zeile Sie
exec
verwenden können, den Shell-Prozess mit der Java ausführbaren Datei zu ersetzen, die Jetty läuft.
Dies ist eine überarbeitete Version des Skripts:
#!/bin/sh
echo Starting Jarvis Program D.
cd "`dirname \"$0\"`"
export ALICE_HOME=.
export SERVLET_LIB=lib/servlet.jar
export ALICE_LIB=lib/aliceserver.jar
export JS_LIB=lib/js.jar
# Set SQL_LIB to the location of your database driver.
export SQL_LIB=lib/mysql_comp.jar
# These are for Jetty; you will want to change these if you are using a different http server.
export HTTP_SERVER_LIBS=lib/org.mortbay.jetty.jar
export PROGRAMD_CLASSPATH=$SERVLET_LIB:$ALICE_LIB:$JS_LIB:$SQL_LIB:$HTTP_SERVER_LIBS
exec java -classpath $PROGRAMD_CLASSPATH -Xms64m -Xmx128m org.alicebot.server.net.AliceServer $1
Unter Berufung auf den Shell-Skript in Objective-C mit mehreren Argumenten:
NSTask *server = [NSTask new];
[server setLaunchPath:@"/bin/sh"];
[server setArguments:[NSArray arrayWithObjects:@"/applications/jarvis/brain/server.sh", @"argument", nil]];
...
Andere Tipps
Mit AMShellWrapperTest.app können Sie filtern (speichern, ...) der stdout Strom von server.sh durch Modifizieren "- (void) appendOutput: (NSString *) Ausgang" in BannerController.m. (... aber vielleicht gibt es einen besseren Weg, dies zu tun ...)
/*
// output from stdout
- modified AMShellWrapper/AMShellWrapperTest/BannerController.m (http://www.harmless.de/cocoa-code.php)
to print server.sh setup information to "Error Messages:" text output field (or Console.app as an
alternative) and the Q & A dialog to the "Output:" text field
- use of default charliebot, http://sourceforge.net/projects/charliebot/, modified only to run server.sh
with complete path (here: ~/Desktop/charliebot/server.sh) in AMShellWrapperTest.app
*/
- (void)appendOutput:(NSString *)output
{
NSMutableString *outputString = [NSMutableString string];
if (
([output rangeOfString:@"Charlie>"].location != NSNotFound ) || \
([output rangeOfString:@"[Charlie] user>"].location != NSNotFound )
) {
[self write: output];
[self write: @"\n"];
} else {
[outputString appendString: output];
//[outputString writeToFile:@"/dev/console" atomically: NO]; // alternative
[errorOutlet setString:[[errorOutlet string] stringByAppendingString: outputString]];
}
}
ja, aber warum ist nicht mein Code (oben geschrieben) nicht?
Ich denke, Ihre „Jarvis>“ Zeile ist die erste Zeile des server.sh ouput Strom, der einige Benutzereingaben erwartet, was bedeutet, dass diese Zeile unvollständig ist ohne abschließende Newline-Zeichen „\ n“. Wenn server.sh in Terminal.app ausgeführt worden wäre, hätte der Benutzer auf die Return-Taste drücken Sie den Dialog fortsetzen zu lassen. Der bedingte Code der while-Schleife (NSNotFound) nicht seine Aufgabe auf dieser unvollständigen Zeile beenden (was zum Abbruch wäre die while-Schleife) steckt und wird.
Sie haben die while-Schleife fallen zu lassen und die ‚readInBackgroundAndNotify‘ -Modus auf NSFileHandle benutzen Sie nicht blockierende E / A-stdout-Stream Verhalten!
Siehe auch: NSTask / NSPipe STDIN hängt auf große Daten, manchmal ...
Also, wenn Sie so wollen, verwandeln Sie den Quelltext von AMShellWrapperTest.app in ein reines Kommandozeilen-Tool, indem Sie den GUI-Code zu entfernen.