将文件写入mac os x中的etc目录

时间:2011-07-29 03:11:19

标签: objective-c xcode macos osx-leopard

我正在尝试将文件写入Mac OS X上的/ etc文件夹。

[[textView string] writeToFile:@"/etc/info.txt" atomically:YES encoding:NSUnicodeStringEncoding error:&error];

它抛出错误,我没有权限在那里写(自然),但我不明白如何获得能够写入系统文件夹的权限。

还有人可以提供简单的例子吗?

请帮忙。 谢谢。

5 个答案:

答案 0 :(得分:3)

写入/ etc /将需要根级别访问。您将不得不询问用户他们的密码,然后运行适当的帮助工具等,为您做实际的写作。

请参阅Authorization Services Tasks文档。

通常,您应该从不以任何理由写入/ etc / 。这是一个系统拥有和控制的目录。当然,考虑到操作系统的unix基础,有些事情可以通过这样做来完成,但仅作为最后手段。

答案 1 :(得分:3)

声明“您永远不应该写入/ etc /”文件夹无效。

写入系统文件夹当然有很多很好的理由 - 如果编写为用户设置内容的企业软件,以便用户不需要手动执行此操作。许多公司甚至要求将Mac批准为工作计算机。这通常使用shell脚本或高级语言(例如Python或Ruby)来完成,但是对于最终用户可用性,UI应用程序也必须能够读取和写入对系统文件夹的更改(例如配置所拥有的文件夹)管理系统)。

我正在编写专业软件,必须始终写入系统文件夹,更改配置文件的内容等需要root权限的文件夹。我没有取得100%的成功,因为MacOSX对此(企业内部使用的企业软件)用例过于不友好,我使用的方法似乎有时无法工作。我最后使用Apple Script对象弹出了管理员密码请求对话框。它很糟糕,但适用于我的主要用例:

 NSString *shellCommand = [[NSString alloc] initWithFormat:@"do shell script \"/bin/bash /usr/bin/nameoftheshellscriptgoeshere.sh\" with administrator privileges"];

 NSAppleScript *script;

 script = [[NSAppleScript alloc] initWithSource:shellCommand];

 NSDictionary* errDict = NULL;

 [script executeAndReturnError:&errDict];

如果你的安装程序将nameofheshellscriptgoeshere.sh(或你给它的任何名称)shell脚本放到/ usr / bin,你就可以在shell脚本中实现你的魔力。

只有在可以使用shell脚本完成管理操作时,此方法才有效。有一种解决方法,但实际上并不是很漂亮:需要使用Objective-C应用程序将配置文件写入系统目录,使用这会导致一个非常繁琐的往返:您创建一个修改后的配置文件到Cocoa可写的文件夹应用程序,然后这个应用程序执行Apple脚本,执行一个单线程shell脚本,将此临时配置文件复制到需要root权限的系统文件夹中的正确位置。这是非常不理想和笨拙的并且引入了对所述shell脚本的依赖性 - 换句话说,如果系统上没有安装shell脚本,UI应用程序将会出现故障。还有很多不必要的分离部分只能维持一个原因:提高Cocoa应用程序的权限很难或不可能,企业软件显然不是设计OSX的设计点。

答案 2 :(得分:1)

好的,经过相当多的研究后,我相信我发现了一种更简单的方法。 首先查看链接:Cocoa - Gaining Root Access for NSFileManager

他们建议使用已经制作的类“BLAuthentication” - 它会为您处理大量的身份验证编码。谷歌它下载,添加到项目并在您的代码中使用。这是一个简单的例子:

id blTmp = [BLAuthentication sharedInstance];

NSString *myCommand = [[NSString alloc] initWithString:@"/bin/cp"];

NSArray *para = [[NSArray alloc] initWithObjects:fileName, @"/etc/", nil];

[blTmp authenticate:myCommand];

if([blTmp isAuthenticated:myCommand] == true) {
    NSLog(@"Authenticated");
    [blTmp executeCommandSynced:myCommand withArgs:para];

} else { NSLog(@"Not Authenticated"); }

[fileName release];
[myCommand release];
[para release];

自然上面的方法并没有完全回答我自己的问题,因为在上面的例子中你不直接写入“/ etc”。相反,首先我必须将文件写入“/ tmp”(或您选择的其他目录),然后在unix中使用“cp”命令,将其复制到“/ etc”(使用“BLAuthentication”进行身份验证)。

这是最简单的方法,我设法找到了。

*注意:此方法在Lion(Mac OS 10.7)中可能不起作用,因为“BLAuthentication”使用不推荐使用的函数“AuthorizationExecuteWithPrivileges”。另外我建议观看WWDC 2011,在那里他们谈论安全性和完成任务的正确方法。但是,如果您需要原型和/或玩游戏,“BLAuthentication”应该可以解决问题。

答案 3 :(得分:1)

对于在谷歌搜索时遇到此问题的其他人:

如果你只是使用" sudo nano目录/ file.name"命令它将打开纳米文本编辑器,然后你可以将文件写入/ etc /目录(或你想要的任何目录),所以我做的是:

' sudo nano /etc/krb5.conf'

打开纳米文本编辑器并同时创建文件' krb5.conf'在etc目录中,我需要做的就是输入代码并编写文件。大约30多岁。

答案 4 :(得分:0)

如何创建可以写入的 /logs 目录:

  1. 禁用 SIP(​​恢复模式,csrutil disable
  2. command + R 打开恢复模式,直到您看到 Apple 标志
  3. 重启
  4. 打开终端
  5. echo 'logs' | sudo tee -a /etc/synthetic.conf
  6. 重启
  7. 或者您可以手动创建一个文件 /etc/synthetic.conf
  8. synthetic.conf
    • #create an empty directory named "logs" at / which may be mounted over
    • logs
  9. 然后重启系统
  10. 确保 **/etc/synthetic.conf** 具有以下权限:
    • root:读、写
    • 轮:阅读
    • 大家:阅读