升级macOS 13.5.2后cron任务无法修改Downloads目录下手动创建的文件
嘿,我来帮你拆解这个问题!你遇到的情况其实是macOS 13.5.2里cron的运行会话和系统隐私保护机制的冲突导致的,核心和文件的com.apple.macl扩展属性有关:
问题根源
你手动创建的foo.txt没有com.apple.macl这个扩展属性,而cron自动生成的bar.txt和whoami.txt都带有这个标记。这个属性是macOS用来跟踪文件权限上下文的——手动创建的文件继承的是你当前用户会话的权限环境,但cron是在独立的系统会话里运行的,哪怕你给了它全磁盘访问权限,它也没有对应的权限上下文去修改这类没有macl标记的文件,所以才会弹出「Operation not permitted」的错误。
解决办法
这里给你几个可行的方案,按优先级推荐:
1. 给手动创建的文件添加macl属性
从cron已经能正常写入的文件里复制这个属性到foo.txt,执行以下命令:
xattr -wx com.apple.macl "$(xattr -px com.apple.macl /Users/me/Downloads/bar.txt)" /Users/me/Downloads/foo.txt
执行后,foo.txt就拥有了和cron创建文件一致的权限标记,cron应该就能正常写入了。
2. 改用launchd替代cron(长期可靠方案)
苹果现在更推荐用launchd来处理定时任务,它能更好地适配macOS的隐私权限系统,避免cron这类老旧工具的权限问题。具体操作如下:
- 在
~/Library/LaunchAgents/目录下创建一个plist文件,比如com.yourname.downloads-writer.plist,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.yourname.downloads-writer</string> <key>ProgramArguments</key> <array> <string>/bin/sh</string> <string>-c</string> <string>echo "Hello World" >> /Users/me/Downloads/foo.txt</string> </array> <key>StartInterval</key> <integer>60</integer> <!-- 每分钟运行一次,单位:秒 --> <key>StandardOutPath</key> <string>/Users/me/Library/Logs/downloads-writer.log</string> <key>StandardErrorPath</key> <string>/Users/me/Library/Logs/downloads-writer-error.log</string> </dict> </plist>
- 加载这个任务:
launchctl load ~/Library/LaunchAgents/com.yourname.downloads-writer.plist
这样任务会在你的用户会话下运行,权限和你手动操作完全一致,就不会再出现权限问题了。如果需要停止任务,执行launchctl unload ~/Library/LaunchAgents/com.yourname.downloads-writer.plist即可。
3. 让cron先创建文件再写入(适合新文件场景)
如果是新文件,你可以在cron任务里先确保文件存在再写入,比如:
* * * * * touch /Users/me/Downloads/foo.txt && echo "Hello World" >> /Users/me/Downloads/foo.txt
不过这个方法只适合还没创建的文件,对你已经存在的foo.txt来说,还是前两个方案更直接。
备注:内容来源于stack exchange,提问作者user1844116

