2010-08-20 130 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

相關問題