用|执行shell命令(管道)使用NSTask [英] executing shell command with | (pipe) using NSTask
问题描述
我正在尝试执行此命令 ps -ef |grep test
使用NSTask,但我无法获得|gTask测试将包含在NSTask中:
I'm trying to execute this comamnd ps -ef | grep test
using NSTask but I can't get the | grep test to be included in the NSTask:
这是我当前正在使用的将ps -ef的输出转换为字符串,然后我需要以某种方式获取过程测试的pid
This is what I'm using currently to get the output of ps -ef into a string then I need to somehow get the pid of the process test
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);
推荐答案
管道是shell提供的功能,例如/bin/sh
.您可以尝试通过这样的外壳启动命令:
Piping is a feature provided by shells, such as /bin/sh
. You may try launching your command via such a shell:
/* ... */
[task setLaunchPath: @"/bin/sh"];
/* ... */
arguments = [NSArray arrayWithObjects: @"-c", @"ps -ef | grep test", nil];
但是,如果让用户提供一个值(而不是像 test
这样的硬编码),则会使程序容易受到Shell注入攻击,这类似于SQL注入.另一个不受此问题困扰的方法是使用管道对象将 ps
的标准输出与 grep
的标准输入连接:
However, if you let the user supply a value (instead of hard-coding e.g. test
), you are making the program susceptible to shell injection attacks, which are kind of like SQL injection. An alternative, which doesn't suffer from this problem, is to use a pipe object to connect the standard output of ps
with the standard input of 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功能来执行与外壳程序遇到 |
字符时相同的步骤.
This uses built-in Foundation functionality to perform the same steps as the shell does when it encounters the |
character.
最后,正如其他人所指出的, grep
的使用是过大的.只需将其添加到您的代码中即可:
Finally as others have pointed out, the usage of grep
is overkill. Just add this to your code:
NSArray *lines = [string componentsSeparatedByString:@"\n"];
NSArray *filteredLines = [lines filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"SELF contains[c] 'test'"]];
这篇关于用|执行shell命令(管道)使用NSTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!