LaunchAgent 脚本无法写入外部驱动器

bre*_*azy 4 python macos bash launchd macos-catalina

macOS Catalina

我有一个应该将文件写入外部驱动器的 python 脚本。如果我手动运行脚本,这会起作用。但是,如果该脚本是从 LaunchAgent bash 脚本启动的,则它无权这样做。

例如,简化的 python 脚本:

with open('/Volumes/nas_1/test/somefile.txt', 'a') as the_file:
                            the_file.write('Hello\n')
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

错误:

PermissionError: [Errno 1] Operation not permitted: '/Volumes/nas_1/test/somefile.txt'
Run Code Online (Sandbox Code Playgroud)

/Volumes/nas_1/test在调试时授予了777 权限,但没有帮助。我应该将 bash 和/或 python 脚本移到其他地方吗?

5t1*_*111 6

我遇到了类似的问题。我通过 rsync 将文件复制到外部驱动器的 bash 脚本在升级到 Catalina 后无法运行。

以下是我为使其再次工作所做的工作:

  • 添加/bin/bashSystem Preferences/ Security & Privacy/Full Disk Access
  • /bin/bash(was /usr/bin/env bash)替换 bash 脚本中的 shebang
  • 从我的 plist 中删除StandardErrorPathStandardOutPath条目(写入日志文件被拒绝,因为它是作为另一个进程产生的)

之后它再次开始工作,但也许有更好的解决方案。