代码之家  ›  专栏  ›  技术社区  ›  alexyorke

从shell脚本objective-c获取结果

  •  1
  • alexyorke  · 技术社区  · 15 年前

    我想运行一个shell脚本,从一个文件或一个objective-c字符串(在代码中)。我还希望将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);
    }
    

    … 下面是我用来运行它的行: mount_idisk("username");

    1 回复  |  直到 8 年前
        1
  •  5
  •   bbum    15 年前

    无法将整个命令行传递给nstask。

    有很好的理由,如果你有任何类型的字符串组合,那么这样做就会充满安全漏洞。字符串组合代码必须完全了解解析shell命令行的所有规则,并且必须转义可能导致任意命令执行的所有字符组合。

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

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

    [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个对象的数组,然后在 doshellscript()。 函数,而不是您需要的两个参数。

    可能是这样的:

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