从shell脚本objective-c获取结果 [英] Get result from shell script objective-c

查看:74
本文介绍了从shell脚本objective-c获取结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个文件或一个objective-c 字符串(在代码中)运行一个shell 脚本.我还希望将 shell 脚本的结果存储到一个变量中.我不希望将 shell 脚本拆分为参数(例如运行时的 setLaunchPath).例如:运行这个 shell 脚本mount_webdav idisk.mac.com/mac_username/Volumes/mac_username"而不是/bin/mount_webdav"然后是参数.有没有办法做到这一点?我现在正在使用 NSTask,但是当我尝试将参数放入其中时,它给我带来了一些错误.代码如下:

I would like to run a shell script, from a file or from an objective-c string (within the code). I would also like the shell script's result to be stored to a variable. I would not like the shell script to be split into arguments (such as setLaunchPath when I run it). For example: running this shell script "mount_webdav idisk.mac.com/mac_username /Volumes/mac_username" instead of "/bin/mount_webdav" then the arguments. Is there anyway to do this? I am using NSTask right now, but it has caused me some errors when I try to put the arguments with it. Here is the posed code:

(一些 .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("用户名");

... Here is the line I am using to run it: mount_idisk("username");

推荐答案

没有办法将整个命令行传递给 NSTask.

There is no way to pass a whole command line to NSTask.

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

For good reason; doing so is rife with security holes if you have any kind of string composition going on. Your string composition code would have to be fully cognizant of all of the rules of parsing a shell command line and would have to escape every possible combination of characters that might lead to arbitrary command execution.

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

The system() C API lets you execute arbitrary commands, but has no mechanism for capturing output directly. It would be easy to add something to your command line that spews the output into a temporary file that you later read, but doing so just adds more security holes above and beyond passing down a whole command line as a single string.

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

Wait... Looks like you have a straightforward bug:

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

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

Why are you setting and then re-setting the task's arguments?

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

Given that your mount_idisk() function is effectively composing the individual arguments and concatenating them together into a single string, why don't you simply stuff all the args into an NSArray and modify doshellscript() to take an array as the second parameter; the array of arguments?

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

You aren't creating the array of arguments correctly.

即:

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

该行正在创建一个包含 4 个对象的数组,这些对象在 doshellscript() 函数中被视为 4 个单独的参数,而不是您需要的两个参数.

That line is creating an array contain 4 objects which are then treated as 4 separate arguments in the doshellscript() function and not the two arguments that you need.

也许是这样的:

NSString *mobileMeUserURL = [@"http://idisk.mac.com/" stringByAppendingString: mac_username];
NSString *localMountPath = [ @"/ /Volumes/" stringByAppendingString:  mac_username];
NSArray *arguments = [NSArray arrayWithObjects: mobileMeUserURL, localMountPath, nil];

这篇关于从shell脚本objective-c获取结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆