gpt4 book ai didi

objective-c - 使用 NSTask 运行用户定义的命令

转载 作者:行者123 更新时间:2023-12-03 17:35:24 28 4
gpt4 key购买 nike

我想执行用户指定的终端命令。例如,用户可能会在文本字段中写入 killall "TextEdit"say "Hello world!",而我想执行该命令。

NSTask 是可行的方法,但我有两个问题:

第一:参数。现在我正在这样做:

NSArray* args = [commandString componentsSeparatedByString: @" "];
[task setArguments: [args subarrayWithRange: NSMakeRange(1, [args count] - 1)]]; // First one is the command name

这是这样做的方法吗?我认为我还没有遇到任何问题,但我看起来并不安全。想象一下:用户写入 killall 'Address Book' 但命令接收作为参数 'AddressBook'?那是行不通的。那么,我应该做什么呢?如何安全地解析参数?

第二:启动路径。只需写入命令的名称,而不是完整的路径,对用户更加友好。所以我想支持这一点,这意味着以编程方式找出只有名称的命令的完整路径。为此,我在 NSTask 上写了一个类别,如下所示:

+ (NSString*)completePathForExec: (NSString*)exec
{
NSTask* task = [[NSTask alloc] init];
NSPipe* pipe = [[NSPipe alloc] init];

NSArray* args = [NSArray arrayWithObject: exec];
[task setLaunchPath: @"/usr/bin/which"];
[task setArguments: args];
[task setStandardOutput: pipe];
[task setStandardError: pipe];

[task launch];
[task waitUntilExit];

NSFileHandle* file = [pipe fileHandleForReading];
NSString* result = [[NSString alloc] initWithData: [file readDataToEndOfFile] encoding: NSASCIIStringEncoding];

if ([result length]) {
if ([result hasSuffix: @"\n"]) { result = [result substringWithRange: NSMakeRange(0, [result length] - 1)]; }

return result;
}
else { return exec; }
}

这看起来效果很好。但是,我如何确定此路径:/usr/bin/which 始终有效?我的意思是:它可以在 10.6、10.7、10.8 等上运行吗?我想我曾经遇到过一个问题,shell 命令的路径随着系统版本的变化而变化,你永远不会太小心。

如果保证路径保持不变,那么这不是问题。如果它改变了,那么我如何知道“探路者的路径”?

最佳答案

您不必重新发明命令行解析轮,这会容易得多。但是,当然,沿着执行任意用户输入的代码的路线是一场安全噩梦(由于用户有权访问系统,因此可能可以直接运行终端)。

具体来说,让 NSTask 使用命令行选项包装对其中一个 shell 的调用,以使其执行任意字符串。

sh -c "ls -alF"

这将允许您将路径传递给 sh 作为启动路径,该路径位于每个系统上的固定位置。 @"-c" 参数告诉 sh 将下一个参数解析为脚本,当然,下一个参数是用户输入的任何内容。

请注意,这也将使用户能够通过管道传输内容。

关于objective-c - 使用 NSTask 运行用户定义的命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12391874/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com