从shell脚本objective-c获取结果

ale*_*rke 1 shell scripting objective-c nsstring

我想从一个文件或一个objective-c字符串(在代码中)运行一个shell脚本.我还希望将shell脚本的结果存储到变量中.我不希望将shell脚本拆分为参数(例如运行时的setLaunchPath).例如:运行此shell脚本"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);
}
Run Code Online (Sandbox Code Playgroud)

...这是我用来运行它的行: mount_idisk("username");

bbu*_*bum 5

无法将整个命令行传递给NSTask.

有充分理由; 如果您正在进行任何类型的字符串组合,那么这样做会充满安全漏洞.您的字符串组合代码必须完全了解解析shell命令行的所有规则,并且必须转义可能导致任意命令执行的每个可能的字符组合.

system()C API,您可以执行任意命令,但没有机制直接捕获输出.在命令行中添加一些东西会很容易,这些东西将输出喷射到您稍后读取的临时文件中,但这样做只会在整个命令行作为单个字符串传递时添加更多安全漏洞.

等等......看起来你有一个简单的错误:

[task setArguments: [NSArray arrayWithObjects: first_cmd_pt, nil]];
[task setArguments: first_cmd_pt];
Run Code Online (Sandbox Code Playgroud)

为什么要设置然后重新设置任务的参数?

鉴于你的mount_idisk()函数有效地组成各个参数并将它们连接成一个字符串,为什么不简单地将所有args填充到一个NSArray并修改doshellscript()为将数组作为第二个参数; 参数数组?


您没有正确创建参数数组.

即:

NSArray *finished_path = [NSArray arrayWithObjects:@"http://idisk.mac.com/", mac_username, @"/ /Volumes/", mac_username, nil];
Run Code Online (Sandbox Code Playgroud)

该行创建一个包含4个对象的数组,然后在doshellscript()函数中将它们视为4个单独的参数,而不是您需要的两个参数.

也许是这样的:

NSString *mobileMeUserURL = [@"http://idisk.mac.com/" stringByAppendingString: mac_username];
NSString *localMountPath = [ @"/ /Volumes/" stringByAppendingString:  mac_username];
NSArray *arguments = [NSArray arrayWithObjects: mobileMeUserURL, localMountPath, nil];
Run Code Online (Sandbox Code Playgroud)