2017-07-20 116 views
0

我有一个程序,它应该引起2档,以使用FileMerge进行比较。如何强制的命令行参数字符串被引用

这并不工作,但偶尔会失败。我怀疑这是当作为参数传递的路径包含空格字符。

下面的代码片段构建任务并启动它。

NSTask *task = [[NSTask alloc] init]; 
    NSPipe *pipe = [NSPipe pipe]; 
    [task setStandardOutput: pipe]; 
    [task setStandardInput:[NSPipe pipe]];  //The magic line that keeps your log where it belongs 
    NSFileHandle *file = [pipe fileHandleForReading]; 
    [task setLaunchPath: @"/bin/sh"]; 
    NSArray *arguments = [NSArray arrayWithObjects: 
          @"-c" , 
          [[NSUserDefaults standardUserDefaults] stringForKey:PREF_COMPARE_COMMAND], 
          @"Compare", // $0 place holder 
          source, 
          target, 
          nil]; 
    [task setArguments:arguments]; 
    [task setEnvironment:[NSDictionary dictionaryWithObject:@"/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin" forKey:@"PATH"]]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(pipeReadCompletionNotification:) 
               name:NSFileHandleReadCompletionNotification 
               object:file]; 
    [file readInBackgroundAndNotify]; 
    [task launch]; 

我已经尝试了很多选项,尝试使用引号将空格或引号括起来,但没有成功。我欢迎任何建议。

典型的参数作为运行的结果是: -

"-c", 
"opendiff $1 $2", 
Compare, 
"/Users/ian/temp/Indian Pacific/RailRes Travel Documentation1.pdf", 
"/Users/ian/temp/Indian Pacific/RailRes Travel Documentation.pdf" 

我试图

[source stringByReplacingOccurrencesOfString:@" " withString:@"\\ "], 
[source stringByReplacingOccurrencesOfString:@" " withString:@"\ "], 

的第一实际插入\\第二产生一个编译错误unknown escape sequence

我试图肯Thomases的建议(知道我的名字没有'

[[@"'" stringByAppendingString:source] stringByAppendingString:@"'"], 
[[@"'" stringByAppendingString:target] stringByAppendingString:@"'"], 

不幸的是这导致了争论

"-c", 
"opendiff $1 $2", 
Compare, 
"'/Users/ian/temp/Indian Pacific/RailRes Travel Documentation1.pdf'", 
"'/Users/ian/temp/Indian Pacific/RailRes Travel Documentation.pdf'" 

,并以同样的方式失败。 /Users/ian/temp/Indian does not exist

编辑_______________________工作守则_____________________________________

NSArray *arguments = [NSArray arrayWithObjects: 
         @"-c" , 
         [NSString stringWithFormat:@"%@ '%@' '%@'", @"opendiff", source, target], 
         nil]; 
+0

您是否尝试用“\”替换“”? – danh

回答

1

对于shell的-c选项采用单个字符串作为参数,而不是多个参数。使用stringWithFormat作为NSString创建完整的shell命令行。在该字符串中,您应该像在终端中那样避开文件名,例如用单引号括住它们。在@"-c"之后传递此字符串作为参数。

HTH

+0

这似乎解决了我的问题。我已将工作代码片段粘贴到我的问题中。我想做一些更多的测试,并且需要对我的代码进行一些其他更改,以使其与保存的首选项一起工作。 – Milliways

0

有一些特殊字符的外壳解释。使用双引号不足以使字符串安全。你可以尝试转义所有的特殊字符,但这可以是挑剔的。

的最简单,最安全的方法是使用单引号。那些告诉外壳看待一切直到下一个单引号没有解释。唯一需要注意的是如果你的字符串本身包含单引号。因此,下面两行会净化你的source论点:

NSString* quoted_source = [source stringByReplacingOccurrencesOfString:@"'" withString:@"'\\''"]; 
quoted_source = [[@"'" stringByAppendingString:quoted_source] stringByAppendingString:@"'"]; 

第一行轮番任何嵌入式单引号将结束单引号(我们会在开始一个出来),转义单引号拿一个我们要替换,其次是新开单引号的地方。第二行在开始时用单引号打开整个事件,在结尾处打开结尾。

+0

感谢您的建议。不幸的是,这似乎没有改善问题。 – Milliways

相关问题