2010-08-20 30 views
1

Je dois exécuter un fichier .sh et obtenir sa sortie. J'ai aussi besoin de voir la configuration du fichier. Le fichier .sh exécute simplement une application java via le terminal.Comment exécuter un fichier .sh à l'aide de NSTask et obtenir sa sortie?

Des idées? Je suis vraiment coincé sur ce .....

Elijah

Le fichier 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 

Mon code actuel:

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

} 

Le NSRunAlertPanel est juste pour vérifier la sortie. Maintenant, mon code se fige et ne parvient même pas au panneau d'alerte.

Répondre

2

Voir la réponse à this question.

Il y a deux choses qui devraient être fixés dans votre script:

  • Le script doit commencer par une tralala. Assurez-vous également que le script a son bit exécutable défini. Étant donné que les variables d'environnement sont définies par rapport au répertoire de script shell, vous devez vous assurer que le répertoire de script est le répertoire en cours.
  • Vous devez exporter les variables d'environnement qui doivent être visibles dans le processus Java.
  • Dans la dernière ligne, vous pouvez utiliser exec pour remplacer le processus shell avec l'exécutable Java qui exécute Jetty.

Voici une version révisée de votre 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 

Invoquer le script shell en Objective-C avec de multiples arguments:

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

Oui. Est-ce que tout cela et il retourne l'écho au début sur le fichier .sh, mais pas l'installation ou le programme final. Il y a également un champ de saisie utilisateur. – objectiveccoder001

+0

Pouvez-vous poster un aperçu de votre script shell? – sakra

+0

oui. Je l'ai mis dans ma question. – objectiveccoder001

1

En utilisant AMShellWrapperTest.app vous pouvez filtrer (sauf , ...) le flux stdout de server.sh en modifiant "- (void) appendOutput: (NSString *) sortie" dans BannerController.m. (... mais peut-être il y a une meilleure façon de le faire ...)

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

oui, mais pourquoi mon code (posté ci-dessus) ne fonctionne pas? – objectiveccoder001

0

yes, but why isn't my code (posted above) not working?

Je suppose que votre « Jarvis> » ligne est la première ligne du flux de ouput server.sh qui attend certains entrée de l'utilisateur, ce qui signifie que cette ligne est incomplète sans un caractère de fin de ligne de fin "\ n". Si server.sh avait été exécuté dans Terminal.app, l'utilisateur devrait appuyer sur la touche de retour pour laisser la boîte de dialogue continuer. Le code conditionnel de la boucle while (NSNotFound) ne peut terminer son travail sur cette ligne incomplète (ce qui consisterait à abandonner la boucle while) et reste bloqué.

Vous devez supprimer la boucle while et utiliser le mode 'readInBackgroundAndNotify' sur NSFileHandle pour obtenir un comportement de flux de sortie stdout E/S non bloquant!

Voir: NSTask/NSPipe STDIN hangs on large data, sometimes...

Donc, si vous le souhaitez, transformer simplement le code source de AMShellWrapperTest.app en un outil de ligne de commande pur en supprimant le code de l'interface graphique.

+0

oui, c'est vrai, mais pourquoi n'imprime-t-il rien d'autre que l'écho? J'ai besoin d'ajouter un argument, mais je ne suis pas sûr de quel argument. – objectiveccoder001