简体   繁体   English

使用响应从可可(obj.c)执行shell脚本

[英]Execute shell script from cocoa (obj.c) with response

I have something like: 我有类似的东西:

- (NSString *)unixSinglePathCommandWithReturn:(NSString *)command
{
NSPipe *newPipe = [NSPipe pipe];
NSFileHandle *readHandle = [newPipe fileHandleForReading];

NSTask *unixTask = [[NSTask alloc] init];
[unixTask setStandardOutput:newPipe];
[unixTask setLaunchPath:@"/bin/sh"];
[unixTask setArguments:[NSArray arrayWithObjects:@"-c", command , nil]]; 
[unixTask launch];
[unixTask waitUntilExit];

NSString *output = [[NSString alloc] initWithData:[readHandle readDataToEndOfFile] encoding:NSUTF8StringEncoding];

return output;
}

But it doesn't work as expected. 但是它没有按预期工作。 I call it when i click a button. 当我单击一个按钮时,我称之为。 If i remove the line with 'waitUntilExit' it works as expected, but only once. 如果我删除带有“ waitUntilExit”的行,它将按预期工作,但只能运行一次。 When it's there, it doesn't work. 当它在那里时,它不起作用。 I tried also some basic commands like 'ls' 'ping -c1 google.com' and stuff like that, but i can't get it to work somehow. 我也尝试了一些基本命令,例如'ls''ping -c1 google.com'之类的东西,但是我无法以某种方式使它工作。 If you have some different approach to run shell scripts in cocoa with receiving the response, please let me now. 如果您在接收到响应时有其他方法在可可中运行shell脚本,请立即让我来。 Thank you all :) 谢谢你们 :)

Hey, Kukosk. 嘿,库科斯克。 There's a comment on CocoaDev about NSLog() issues when running an NSTask. 运行NSTask时, CocoaDev上有关于NSLog()问题的评论。 The fix is to set a pipe for stdin before launching the task: 解决方法是在启动任务之前为stdin设置管道:

[task setStandardInput:[NSPipe pipe]];

If you're relying on NSLog() only to check whether the task has run, this might fix your problem. 如果仅依靠NSLog()来检查任务是否已运行,则可能会解决您的问题。 Alternatively, you could try to present output in your GUI instead of using NSLog() . 或者,您可以尝试在GUI中呈现output ,而不是使用NSLog()

The problem is that you aren't emptying the output buffers of the task. 问题是您没有清空任务的输出缓冲区。 You can't simply launch a task and waitUntilDone unless the task also emits an extremely small amount of data. 除非任务还发出非常少量的数据,否则您不能简单地启动任务并使用waitUntilDone

waitUntilDone will obviously not work at all with a task that never exits. 对于永远不会退出的任务, waitUntilDone显然根本无法工作。

For a task that emits any quantity of output, you need to set it up such that the output is read as it is generated. 对于发出任何数量的输出的任务,您需要对其进行设置,以便在生成输出时对其进行读取。 Typically, you use readInBackgroundAndNotify or a variant therein. 通常,您使用readInBackgroundAndNotify或其中的一个变体。

In any case, the top of the class description for NSTask has both links to the conceptual guide and to a series of examples that cover this. 无论如何, NSTask的类描述的NSTask都有指向概念指南的链接,以及指向该指南的一系列示例的链接。

Ah, there's a very important line in the docs you seem to have missed, one of those irritations that NextStep seems to like: "An NSTask object can only be run once. Subsequent attempts to run the task raise an error." 嗯,您似乎错过了文档中的一条非常重要的一行,NextStep似乎很讨厌这些刺激之一:“ NSTask对象只能运行一次。随后尝试运行任务会引发错误。”

So, bag the wait, and add [unixTask release] before the return. 因此,请等待,然后在返回之前添加[unixTask release]。 When you want to run it again, remake the task. 当您想再次运行它时,请重新执行任务。

NSTimer is like this. NSTimer就是这样。

For different approaches to run shell scripts in Cocoa have a look at AMShellWrapper, PseudoTTY.app or OpenFileKiller! 对于在Cocoa中运行shell脚本的不同方法,请查看AMShellWrapper,PseudoTTY.app或OpenFileKiller!

http://www.cocoadev.com/index.pl?NSTask http://www.cocoadev.com/index.pl?NSTask

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM