Получить результат из shell-скрипта target-c - PullRequest
1 голос
/ 29 ноября 2009

Я хотел бы запустить скрипт оболочки из файла или из строки Objective-C (внутри кода). Я также хотел бы, чтобы результат сценария оболочки был сохранен в переменной. Я не хотел бы, чтобы скрипт оболочки был разбит на аргументы (например, setLaunchPath, когда я его запускаю). Например: запустить этот сценарий оболочки "mount_webdav idisk.mac.com/mac_username / Volumes / mac_username" вместо "/ bin / mount_webdav", затем аргументы Есть какой-либо способ сделать это? Я использую NSTask прямо сейчас, но это вызвало у меня некоторые ошибки, когда я пытаюсь привести аргументы с ним. Вот этот код:

(часть файла .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);
}

... Вот строка, которую я использую для запуска: mount_idisk("username");

1 Ответ

5 голосов
/ 29 ноября 2009

Нет способа передать всю командную строку в NSTask.

по уважительной причине; это изобилует дырами в безопасности, если у вас есть какая-либо струнная композиция. Ваш код композиции строк должен быть полностью осведомлен обо всех правилах синтаксического анализа командной строки оболочки и должен избегать всех возможных комбинаций символов, которые могут привести к выполнению произвольной команды.

API system() C позволяет выполнять произвольные команды, но не имеет механизма для непосредственного захвата вывода. Было бы легко добавить что-то в вашу командную строку, которое изменит вывод во временный файл, который вы позже прочитаете, но при этом просто добавляет больше дыр в безопасности, помимо того, что вся командная строка передается как одна строка.

Подождите ... Похоже, у вас есть простая ошибка:

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

Почему вы устанавливаете, а затем заново устанавливаете аргументы задачи?

Учитывая, что ваша функция mount_idisk() эффективно объединяет отдельные аргументы и объединяет их в одну строку, почему бы вам просто не собрать все аргументы в NSArray и не изменить doshellscript(), чтобы получить массив как второй параметр; массив аргументов?

<Ч />

Вы неправильно создаете массив аргументов.

А именно:

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

Эта строка создает массив, содержащий 4 объекта, которые затем обрабатываются как 4 отдельных аргумента в функции doshellscript(), а не как два аргумента, которые вам нужны.

Может быть что-то вроде:

NSString *mobileMeUserURL = [@"http://idisk.mac.com/" stringByAppendingString: mac_username];
NSString *localMountPath = [ @"/ /Volumes/" stringByAppendingString:  mac_username];
NSArray *arguments = [NSArray arrayWithObjects: mobileMeUserURL, localMountPath, nil];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...