Pregunta

Me gustaría ejecutar un script de shell, desde un archivo o desde una cadena de Objective-C (dentro del código). También me gustaría que el resultado del script de shell se almacene en una variable. No me gustaría que el script de shell se dividiera en argumentos (como setLaunchPath cuando lo ejecuto). Por ejemplo: ejecutar este script de shell " mount_webdav idisk.mac.com/mac_username / Volumes / mac_username " en lugar de " / bin / mount_webdav " entonces los argumentos. ¿Hay alguna forma de hacer esto? Estoy usando NSTask en este momento, pero me ha causado algunos errores cuando trato de poner los argumentos con él. Aquí está el código presentado:

(algunos archivos .m)

 NSString *doshellscript(NSString *cmd_launch_path, NSString *first_cmd_pt) {

 NSTask *task = [[NSTask alloc] init]; // Make a new task

 [task setLaunchPath: cmd_launch_path]; // Tell which command we are running

 [task setArguments: [NSArray arrayWithObjects: first_cmd_pt, nil]];

 [task setArguments: first_cmd_pt];

 NSPipe *pipe = [NSPipe pipe];

 [task setStandardOutput: pipe];

 [task launch];

  NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];

  NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];

  [task release]; //Release the task into the world, thus destroying it.

  return string;
}


NSString *mount_idisk(NSString *mac_username) {

 doshellscript(@"/bin/mkdir", [@"/Volumes/" stringByAppendingString:mac_username]);

 NSString *path_tmp = [mac_username stringByAppendingString: @"/ /Volumes/"];

 NSString *idisk_path = [path_tmp stringByAppendingString:mac_username];

 //NSLog(@"%@", [@" http://idisk.mac.com/" stringByAppendingString: idisk_path]);

 NSString *finished_path = [@"http://idisk.mac.com/" stringByAppendingString: idisk_path];

 doshellscript(@"/sbin/mount_webdav", finished_path);
}

... Aquí está la línea que estoy usando para ejecutarlo: mount_idisk (" nombre de usuario ");

¿Fue útil?

Solución

No hay forma de pasar una línea de comando completa a NSTask.

Por una buena razón; hacerlo está plagado de agujeros de seguridad si tienes algún tipo de composición de cuerda. Su código de composición de cadena tendría que ser plenamente consciente de todas las reglas de análisis de una línea de comando de shell y debería escapar de todas las combinaciones posibles de caracteres que podrían conducir a la ejecución arbitraria de comandos.

El system () C API le permite ejecutar comandos arbitrarios, pero no tiene ningún mecanismo para capturar la salida directamente. Sería fácil agregar algo a su línea de comando que arroje la salida a un archivo temporal que luego lea, pero al hacerlo solo agrega más agujeros de seguridad más allá de pasar una línea de comando completa como una sola cadena.

Espera ... Parece que tienes un error directo:

[task setArguments: [NSArray arrayWithObjects: first_cmd_pt, nil]];
[task setArguments: first_cmd_pt];

¿Por qué configura y luego vuelve a configurar los argumentos de la tarea?

Dado que su función mount_idisk () está componiendo efectivamente los argumentos individuales y los concatena en una sola cadena, ¿por qué no simplemente rellena todos los argumentos en un NSArray y modifique doshellscript () para tomar una matriz como segundo parámetro; la matriz de argumentos?


No está creando la matriz de argumentos correctamente.

A saber:

NSArray *finished_path = [NSArray arrayWithObjects:@"http://idisk.mac.com/", mac_username, @"/ /Volumes/", mac_username, nil];

Esa línea está creando una matriz que contiene 4 objetos que luego se tratan como 4 argumentos separados en la función doshellscript () y no los dos argumentos que necesita.

Tal vez algo como:

NSString *mobileMeUserURL = [@"http://idisk.mac.com/" stringByAppendingString: mac_username];
NSString *localMountPath = [ @"/ /Volumes/" stringByAppendingString:  mac_username];
NSArray *arguments = [NSArray arrayWithObjects: mobileMeUserURL, localMountPath, nil];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top