Domanda

Ho bisogno di eseguire un file .sh e ottenere la sua uscita. Ho bisogno di vedere la configurazione del file pure.

Il file .sh esegue semplicemente un'applicazione Java attraverso il terminale.

Tutte le idee? Sono davvero bloccato su questo .....

Elia

Il file server.sh:

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

Il mio codice corrente:

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, @"", @"", @"");

}

Il NSRunAlertPanel è solo per controllare l'uscita. Ora il mio codice è il congelamento e nemmeno arrivare alla alertpanel.

È stato utile?

Soluzione

Si veda la risposta a questa domanda .

Ci sono un paio di cose che dovrebbero essere fissata nello script:

  • Lo script dovrebbe iniziare con una shebang. Assicurarsi inoltre che il script ha il primo bit eseguibile.
  • Perché le variabili d'ambiente sono impostati relativamente alla directory script di shell, è necessario assicurarsi che la directory script è la directory corrente.
  • È necessario esportare le variabili di ambiente che dovrebbero essere visibili al processo Java.
  • Nell'ultima riga è possibile utilizzare exec per sostituire il processo di shell con l'eseguibile Java che viene eseguito Jetty.

Ecco una versione rivista dello script:

#!/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

Invocare lo script di shell in Objective-C con più argomenti:

NSTask *server = [NSTask new];
[server setLaunchPath:@"/bin/sh"];
[server setArguments:[NSArray arrayWithObjects:@"/applications/jarvis/brain/server.sh", @"argument", nil]];
...

Altri suggerimenti

Usando AMShellWrapperTest.app è possibile filtrare (Save, ...) il flusso stdout di server.sh modificando "- (void) appendOutput: (NSString *) Uscita" in BannerController.m. (... ma forse c'è un modo migliore per fare questo ...)

/*
// 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]];
        }
}
  

Sì, ma perché non è il mio codice (postato sopra) non funziona?

Credo che il vostro "Jarvis>" linea è la prima linea del server.sh ouput torrente che si aspetta un po 'di input dell'utente, il che significa che questa linea è incompleta senza un carattere di nuova riga di terminazione "\ n". Se server.sh era stato eseguito in Terminal.app, l'utente dovrà premere il tasto Invio per lasciare che il dialogo continui. Il codice condizionale del ciclo while (NSNotFound) non può terminare il suo lavoro su questa linea incompleta (che sarebbe quello di interrompere il ciclo while) e si blocca.

Si deve cadere il ciclo while e utilizzare la modalità 'readInBackgroundAndNotify' sul NSFileHandle per ottenere non-blocking I O stdout comportamento / ruscello!

See: NSTask / NSPipe STDIN si blocca su dati di grandi dimensioni, a volte ...

Quindi, se vi piace, basta trasformare il codice sorgente di AMShellWrapperTest.app in uno strumento da riga di comando pura rimuovendo il codice della GUI.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top