用|执行shell命令(管道)使用NSTask

时间:2011-07-22 03:10:24

标签: objective-c cocoa

我正在尝试使用NSTask执行此comamnd ps -ef | grep test,但我无法得到grep test包含在NSTask中:

这就是我目前用来将ps -ef的输出变成字符串然后我需要以某种方式得到过程测试的pid

NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/ps"];

NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-ef", nil];
[task setArguments: arguments];    
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];

NSFileHandle *file;
file = [pipe fileHandleForReading];

[task launch];

NSData *data;
data = [file readDataToEndOfFile];

NSString *string;
string = [[NSString alloc] initWithData: data
                               encoding: NSUTF8StringEncoding];
NSLog (@"got\n%@", string);

2 个答案:

答案 0 :(得分:18)

管道是shell提供的功能,例如/bin/sh。您可以尝试通过这样的shell启动命令:

/* ... */
[task setLaunchPath: @"/bin/sh"];
/* ... */
arguments = [NSArray arrayWithObjects: @"-c", @"ps -ef | grep test", nil];

但是,如果你让用户提供一个值(而不是硬编码,例如test),你就会使程序容易受到shell注入攻击,这有点像SQL注入。另一个没有遇到此问题的方法是使用管道对象将ps的标准输出与grep的标准输入连接起来:

NSTask *psTask = [[NSTask alloc] init];
NSTask *grepTask = [[NSTask alloc] init];

[psTask setLaunchPath: @"/bin/ps"];
[grepTask setLaunchPath: @"/bin/grep"];

[psTask setArguments: [NSArray arrayWithObjects: @"-ef", nil]];
[grepTask setArguments: [NSArray arrayWithObjects: @"test", nil]];

/* ps ==> grep */
NSPipe *pipeBetween = [NSPipe pipe];
[psTask setStandardOutput: pipeBetween];
[grepTask setStandardInput: pipeBetween];

/* grep ==> me */
NSPipe *pipeToMe = [NSPipe pipe];
[grepTask setStandardOutput: pipeToMe];

NSFileHandle *grepOutput = [pipeToMe fileHandleForReading];

[psTask launch];
[grepTask launch];

NSData *data = [grepOutput readDataToEndOfFile];

/* etc. */

这使用内置的Foundation功能来执行shell遇到|字符时所执行的相同步骤。

最后正如其他人所指出的那样,使用grep是过度的。只需将其添加到您的代码中:

NSArray *lines = [string componentsSeparatedByString:@"\n"];
NSArray *filteredLines = [lines filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"SELF contains[c] 'test'"]];

答案 1 :(得分:0)

您可能需要在启动任务之前调用[task waitUntilExit],以便在读取输出之前该过程可以完成运行。