Java 如何使用NSTask运行.sh文件并获得其输出?

Java 如何使用NSTask运行.sh文件并获得其输出?,java,objective-c,cocoa,jetty,nstask,Java,Objective C,Cocoa,Jetty,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 dat

我需要运行一个.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

参见对的回答

在您的脚本中,有两件事需要解决:

#!/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脚本目录设置的,所以需要确保脚本目录是当前目录
  • 您需要导出Java进程应该可见的环境变量
  • 在最后一行中,您可以使用
    exec
    将shell进程替换为运行Jetty的Java可执行文件
以下是您的脚本的修订版本:

#!/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
使用多个参数调用Objective-C中的shell脚本:

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

在您的脚本中,有两件事需要解决:

#!/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脚本目录设置的,所以需要确保脚本目录是当前目录
  • 您需要导出Java进程应该可见的环境变量
  • 在最后一行中,您可以使用
    exec
    将shell进程替换为运行Jetty的Java可执行文件
以下是您的脚本的修订版本:

#!/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
使用多个参数调用Objective-C中的shell脚本:

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

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


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

是的,但是为什么我的代码(贴在上面)不起作用呢

我猜您的“Jarvis>”行是server.sh输出流的第一行,它需要一些用户输入,这意味着如果没有终止换行符“\n”,这一行是不完整的。如果server.sh已在Terminal.app中运行,则用户必须按回车键才能让对话框继续。while循环的条件代码(NSNotFound)无法在此不完整的行上完成其作业(这将中止while循环),并被卡住

您必须放弃while循环,并在NSFileHandle上使用“readInBackgroundAndNotify”模式来获得非阻塞I/O标准输出流行为

见:

因此,如果您愿意,只需通过删除GUI代码将AMShellWrapperTest.app的源代码转换为纯命令行工具即可

是的,但是为什么我的代码(贴在上面)不起作用呢

我猜您的“Jarvis>”行是server.sh输出流的第一行,它需要一些用户输入,这意味着如果没有终止换行符“\n”,这一行是不完整的。如果server.sh已在Terminal.app中运行,则用户必须按回车键才能让对话框继续。while循环的条件代码(NSNotFound)无法在此不完整的行上完成其作业(这将中止while循环),并被卡住

您必须放弃while循环,并在NSFileHandle上使用“readInBackgroundAndNotify”模式来获得非阻塞I/O标准输出流行为

见:


因此,如果您愿意,只需通过删除GUI代码将AMShellWrapperTest.app的源代码转换为纯命令行工具。

Yes。完成所有这些操作后,它会在.sh文件的开头返回回显,但不会返回设置或最终程序。还有一个用户输入字段。您可以发布shell脚本的大纲吗?我认为NSTask不会像终端那样让我查看.sh文件的设置。好的,谢谢!然后我会用目录:/applications/jarvis/brain的路径替换“dirname”吗?好的。。。看起来它冻结了我的代码。。。。。我把它贴在问题上。是的。完成所有这些操作后,它会在.sh文件的开头返回回显,但不会返回设置或最终程序。还有一个用户输入字段。您可以发布shell脚本的大纲吗?我认为NSTask不会像终端那样让我查看.sh文件的设置。好的,谢谢!然后我会用目录:/applications/jarvis/brain的路径替换“dirname”吗?好的。。。看起来它冻结了我的代码。。。。。我把它贴在问题上了。是的,没错,但是为什么它除了回声之外什么都不打印呢?我需要添加一个参数,但我不确定是什么参数。是的,这是真的,但为什么它除了回声之外什么都不打印?我需要添加一个论点,但我不确定是什么论点。