2010-08-20 129 views
1

我需要运行.sh文件并获取其输出。我还需要查看文件的设置。如何使用NSTask运行.sh文件并获取其输出?

.sh文件只是通过终端运行一个Java应用程序。

任何想法?我真的卡在这.....

利亚

的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 

我当前的代码:

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

} 

的NSRunAlertPanel只是为检查输出。现在我的代码冻结了,甚至没有进入alertpanel。

回答

2

查看答案this question

有一对夫妇的事情,应该是固定在你的脚本:

  • 脚本应该有 家当开始。还要确保 脚本的可执行位已设置。
  • 因为环境变量是相对于shell脚本目录设置的,所以您需要确保脚本目录是当前目录。
  • 您需要导出应该对Java进程可见的环境变量。
  • 在最后一行,您可以使用exec替换运行Jetty的Java可执行文件的shell进程。

这里是你的脚本的修订版本:

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

调用shell脚本在Objective-C使用多个参数:

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

是的。做了所有这些,它在.sh文件的开始处返回回声,但不是设置或最终程序。还有一个用户输入字段。 – objectiveccoder001 2010-08-20 13:15:59

+0

你可以发布你的shell脚本的大纲吗? – sakra 2010-08-20 15:41:09

+0

是的。我把它写在我的问题上。 – objectiveccoder001 2010-08-20 17:41:46

1

使用AMShellWrapperTest.app可以过滤(保存,...)通过在BannerController.m中修改“ - (void)appendOutput:(NSString *)output”来实现server.sh的stdout流。 (...但也许有更好的方法来做到这一点...)

/* 
// 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

是的,但为什么不是我的代码(上面发布)不工作? – objectiveccoder001 2010-08-21 22:01:35

0

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

我想你“贾维斯>”线是server.sh输出流的第一行预计,一些用户输入,这意味着如果没有终止的换行符“\ n”,这一行是不完整的。如果server.sh已经在Terminal.app中运行,用户将不得不按回车键让对话继续。 while循环(NSNotFound)的条件代码无法在这个不完整的行上完成它的工作(这将会中止while循环)并被卡住。

您必须删除while循环并在NSFileHandle上使用'readInBackgroundAndNotify'模式来获得非阻塞I/O标准输出流行为!

请参见:NSTask/NSPipe STDIN hangs on large data, sometimes...

所以,如果你喜欢,只是去掉GUI代码转换AMShellWrapperTest.app的源代码转换成一个纯粹的命令行工具。

+0

是的,这是真的,但为什么它不打印除echo之外的任何东西?我需要添加一个参数,但我不确定什么论点。 – objectiveccoder001 2010-08-22 13:17:39

相关问题