开发者

Objective-C shell escaping

How do you escape arguments for shell commands in ObjectivesC?

The ruby library ha开发者_JAVA技巧s Shellwords (shellescape for NSString, shelljoin for NSArray, I don't need shellsplit). And I really need an escaped string, I know about NSTask, I don't need to execute that command.


Escaping content for the shell is pretty easy if you use single quotes. The important thing to understand about shell quoting is that you can concatenate strings with different quoting styles, and even unquoted strings, in the same argument. For example, 'one two'three" four" mixes all 3 quoting styles, and ends up passing the string "one twothree four" as a single argument. The other thing to understand is that outside of quoting, you can backslash-escape special characters. The end result of this is a string like 'one two'\''three four' evaluates to the string "one two'three four", with the single quote. By using this trick, you can easily quote any string by replacing all single-quotes with the sequence '\'' and then wrapping the entire string in a single pair of single quotes.

If you have the following string:

I don't like shell quoting

and you apply this simple transformation you end up with

'I don'\''t like shell quoting'

and this gets evaluated back to the original string by the shell and handled as a single argument.

The following category on NSString should accomplish this transformation easily:

@implementation NSString (ShellQuoting)
// prefixed with "my", replace with your prefix of choice
- (NSString *)myStringByShellquotingString:(NSString *)str {
    NSMutableString *result = [NSMutableString stringWithString:str];
    [result replaceOccurrencesOfString:@"'" withString:@"'\\''" options:0 range:NSMakeRange(0, [result length])];
    [result insertString:@"'" atIndex:0];
    [result appendString:@"'"];
    return result;
}
@end


See the list of methods of NSString here. There are many obscure ones, but I don't think there's any that fits your job. You need to write one yourself.

If that method is called relatively infrequently, I would just call ruby binary from inside Objective-C and use shellescape, and then retrieve the result; it's stupid to re-invent the wheel.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜