【发布时间】:2020-02-28 19:22:15
【问题描述】:
macOS 卡塔利娜
我有一个 python 脚本应该将文件写入外部驱动器。如果我手动运行脚本,这将有效。但是,如果脚本是从 LaunchAgent bash 脚本启动的,则它没有这样做的权限。
以简化的 python 脚本为例:
with open('/Volumes/nas_1/test/somefile.txt', 'a') as the_file:
the_file.write('Hello\n')
LaunchAgent 启动的 Bash 脚本位于 /Applications:
#!/bin/bash
#Start test script only if it is not running
if [ "$(ps -ef | grep -v grep | grep python_test.py | wc -l)" -le 0 ]
then
echo "Python Test Starting"
/Users/admin-user/.venvs/test/bin/python /Users/admin-user/projects/test/scripts/python_test.py
else
echo "Python Test Already Running"
fi
plist 位于~/Library/LaunchAgents:
<?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>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:</string>
</dict>
<key>Label</key>
<string>com.test.agent</string>
<key>Program</key>
<string>/Applications/runTest.sh</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>LaunchOnlyOnce</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/runTest.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/runTest.stderr</string>
</dict>
</plist>
错误:
PermissionError: [Errno 1] Operation not permitted: '/Volumes/nas_1/test/somefile.txt'
我在调试时授予了/Volumes/nas_1/test 777 权限,但这并没有帮助。我应该将 bash 和/或 python 脚本移到其他地方吗?
【问题讨论】:
-
我对 MacOS 不太熟悉,这里有一个可能的假设场景:
LaunchAgent或launchd以自己的特权运行。一旦您使用您的权限创建了somefile.txt,launchd就无权打开要附加的文件。请删除现有文件,然后重试。 -
删除现有文件并使用
with open('/Volumes/nas_1/test/somefile.txt', 'w') as the_file:时存在相同问题。无论如何,我的真实脚本每次都会创建一个新文件。为了简单起见,我提供了该示例,因为我看到创建 txt 文件并运行我的完整脚本的相同行为。 macOS Catalina 为启动守护进程和代理引入了一些隐私保护:developer.apple.com/documentation/macos_release_notes/…。此脚本和 LaunchAgent 配置在 Catalina 更新之前有效。 -
对不起,我跑题了。顺便说一句,如果您将目标更改为内部驱动器会发生什么?
-
将目的地更改为“~/Desktop”有效。如果我无法完成这项工作,我将让它写入本地目录,然后让 cron 每分钟将所有内容移动到外部驱动器。
-
我无法弄清楚导致差异的原因,但我认为您的解决方法是有道理的。很抱歉无法提供帮助。
标签: python bash macos launchd macos-catalina