2011-07-22 58 views
9

我想執行這個comamnd ps -ef | grep test使用NSTask,但我不能得到|被列入NSTask的grep測試:使用|執行shell命令(管道)使用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); 
+0

爲什麼不在您的程序中進行過濾呢?管道grep會更慢。 – 2011-09-10 12:52:25

回答

0

在啓動任務之前,您可能需要調用[任務waitUntilExit],以便在讀取輸出之前該過程可以完成運行。

+0

進程完成並獲得ps -ef的輸出。但我也需要對該輸出進行grep測試。 – ed1t

15

管道是shell提供的功能,如/bin/sh。您可以嘗試通過這樣的外殼啓動您的命令:

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

但是,如果你讓用戶提供一個值(而不是硬編碼如test),你可以將這個程序容易受到殼注入攻擊,這有點像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. */ 

此使用內置的基礎功能,以執行相同的當shell遇到|字符時會執行這些步驟。

最後,正如其他人指出的,grep的使用是矯枉過正。只需將其添加到您的代碼中:

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

+1表示「管道是貝殼提供的功能......」。我正在尋找多年的原因! – Eonil