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

Posted

技术标签:

【中文标题】将文件写入mac os x中的etc目录【英文标题】:Write file to etc directory in mac os x 【发布时间】:2011-07-29 03:11:18 【问题描述】:

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

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

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

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

请帮忙。 谢谢。

【问题讨论】:

【参考方案1】:

声称“您永远不应该写入 /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];

如果您的安装程序将 shellscriptgoeshere.sh 的名称(或您为其指定的任何名称)shell 脚本放置到 /usr/bin,您就可以在 shell 脚本中施展魔法。

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

【讨论】:

【参考方案2】:

写入 /etc/ 需要 root 级别的访问权限。您必须向用户询问他们的密码,然后运行适当的帮助工具等来为您进行实际的写作。

请参阅Authorization Services Tasks 文档。

一般来说,您应该永远不要出于任何原因写入/etc/。那是一个系统拥有和控制的目录。当然,考虑到操作系统的 unix 基础,这样做可以做一些事情,但只能作为最后的手段。

【讨论】:

是否可以获得简单的示例代码来执行文件的授权编辑? 并非如此——文档包含指向示例代码 IIRC 的链接。或者搜索其中包含的 API。很难。还有,你为什么要写信给 /etc/? 我需要不时更新其中的几个文件。 哪些文件?为什么?明确禁止写入 /etc。 底线是我需要能够在 /etc/ 中写入文件并设置文件的权限。我可以在 bash 脚本中编写所有这些,但我想为例程制作小应用程序。我知道与写入 /etc 相关的所有问题,这不是本主题的一致意见。我只想知道如何授权我的代码写入/etc/。【参考方案3】:

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

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

'sudo nano /etc/krb5.conf'

它打开了 nano 文本编辑器并同时在 etc 目录中创建了文件“krb5.conf”,然后我需要做的就是输入代码并编写文件。花了大约 30 秒。

【讨论】:

【参考方案4】:

好的,经过大量研究后,我相信我找到了一种或多或少简单的方法。 先看看链接: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”应该可以解决问题。

【讨论】:

更新:我在 Mac OS 10.7 上测试我的应用程序并且“AuthorizationExecuteWithPrivileges”工作正常。【参考方案5】:

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

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

【讨论】:

以上是关于将文件写入mac os x中的etc目录的主要内容,如果未能解决你的问题,请参考以下文章

无法写入文件 pri:无法在 QT mac os 中创建父目录

如何在Mac OS X上面指定Eclipse启动时用指定的某一版本JDK

使用 OS X 沙箱写入多个文件

Mac OS X(或 Mono)中的 MS Access .mdb 文件

在写入已装入目录中的文件时,docker容器会增加内存使用量

如何在 OS X 上写入本地应用程序支持目录