2017-07-20 35 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

相關問題