用|执行shell命令(管道)使用NSTask [英] executing shell command with | (pipe) using NSTask

查看:66
本文介绍了用|执行shell命令(管道)使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆