2011-07-22 22 views
9

Estoy tratando de ejecutar este comando ps -ef | grep test usando NSTask pero no puedo obtener el | prueba de grep para ser incluido en el NSTask:ejecutando el comando de shell con | (tubería) usando NSTask

Esto es lo que estoy usando actualmente para obtener la salida de ps-ef en una cadena y luego tengo que conseguir de alguna manera el pid del proceso de prueba

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

¿Por qué no hace el filtrado en su programa? La tubería para grep será más lenta. El proceso –

Respuesta

0

Es posible que deba llamar a [task waitUntilExit] antes de iniciar la tarea, de modo que el proceso pueda finalizar la ejecución antes de leer la salida.

+0

se finaliza y obtengo el resultado de ps -ef en un String. Pero también necesito hacer una prueba grep en esa salida. – ed1t

15

La canalización es una característica proporcionada por shells, como /bin/sh. Usted puede tratar de lanzar su comando a través de una concha como:

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

Sin embargo, si deja que el usuario proporciona un valor (en lugar de codificar duro por ejemplo test), que está haciendo el programa susceptibles a bombardear los ataques de inyección, lo cual son como una inyección SQL. Una alternativa, que no sufre de este problema, es el uso de un objeto de tubería para conectar la salida estándar de ps con la entrada estándar de 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. */ 

Esto utiliza funcionalidad integrada Fundación para realizar la misma pasos como el shell cuando encuentra el carácter |.

Por último, como han señalado otros, el uso de grep es excesivo. Simplemente agregue esto a su código:

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

+1 por mencionar que "La tubería es una característica proporcionada por los proyectiles, ...". ¡Estaba buscando la razón por años! – Eonil

Cuestiones relacionadas