簡體   English   中英

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

[英]executing shell command with | (pipe) using NSTask

我正在嘗試執行此命令ps -ef | grep test ps -ef | grep test使用 NSTask 但我無法得到 | grep 測試要包含在 NSTask 中:

這就是我目前用來將 ps -ef 的 output 轉換為字符串然后我需要以某種方式獲取進程測試的 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);

管道是 shell 提供的一項功能,例如/bin/sh 您可以嘗試通過這樣的 shell 啟動您的命令:

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

但是,如果您讓用戶提供一個值(而不是硬編碼,例如test ),您會使程序容易受到 shell 注入攻擊,這有點像 SQL 注入攻擊。 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 功能來執行與 shell 在遇到| 特點。

最后,正如其他人所指出的, grep的使用是多余的。 只需將其添加到您的代碼中:

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

您可能需要在啟動任務之前調用 [task waitUntilExit],以便在讀取 output 之前進程可以完成運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM