MacOS下Crontab执行Python脚本遇权限限制问题求助
问题描述
我尝试通过crontab定时执行Python脚本,第一种写法:
* * * * * /Users/myUser/Documents/Code/Tools/appName/myScript.py >>/tmp/crontab.log 2>/tmp/crontab.err
还试过在crontab里用cd命令,以及在脚本里调用os.chdir()的组合:
* * * * * cd Documents/Code/Tools/app-use_tracker/ && /usr/local/bin/python3 app-use_tracker.py >>/tmp/crontab.log 2>/tmp/crontab.err
但始终在stderr里收到错误:
/usr/local/bin/python3: can't open file 'app-use_tracker.py': [Errno 1] Operation not permitted
看到过给Python3授予「完全磁盘访问权限」的方案,但觉得不安全,也试过给脚本设777权限,问题依旧。需要两种解决方案之一或两者:
- 让Python3脚本正常运行的替代思路;
- 确定Python3可读写的文件系统路径。
一、让脚本正常运行的替代思路
1. 用绝对路径直接调用脚本
crontab的运行环境和用户登录环境不一样,相对路径容易出错。直接用脚本的完整绝对路径调用,同时指定Python解释器的绝对路径:
* * * * * /usr/local/bin/python3 /Users/myUser/Documents/Code/Tools/app-use_tracker/app-use_tracker.py >>/tmp/crontab.log 2>/tmp/crontab.err
2. 迁移脚本到无权限限制的目录
把脚本从Documents这类受macOS隐私保护的目录,移到用户完全可控的路径,比如~/Projects、~/Library/Application Support/你的自定义目录,然后修改crontab命令指向新路径即可。
3. 用launchd替代crontab(macOS专属)
macOS的launchd比crontab更适配系统权限机制,创建一个plist配置文件放在~/Library/LaunchAgents/下,比如com.user.app-use-tracker.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.user.app-use-tracker</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/python3</string> <string>/Users/myUser/Documents/Code/Tools/app-use_tracker/app-use_tracker.py</string> </array> <key>StandardOutPath</key> <string>/tmp/crontab.log</string> <key>StandardErrorPath</key> <string>/tmp/crontab.err</string> <key>StartInterval</key> <integer>60</integer> <!-- 每分钟执行一次 --> </dict> </plist>
然后加载配置:
launchctl load ~/Library/LaunchAgents/com.user.app-use-tracker.plist
需要开机自动加载的话,加上-w参数:
launchctl load -w ~/Library/LaunchAgents/com.user.app-use-tracker.plist
二、确定Python3可安全读写的路径
1. 系统临时目录
/tmp和/var/tmp是系统默认开放的临时目录,Python3在任何环境下都有读写权限,可以把脚本的临时文件、输出内容放在这里,也可以临时把脚本移到/tmp测试(注意/tmp重启后会清空)。
2. 用户专属无限制目录
用户主目录下的~/Desktop、~/Projects、~/Library/Application Support这些路径,不受macOS隐私权限限制,Python3在crontab环境下默认能正常读写。
3. 手动验证路径权限
可以在crontab里加一条测试命令,快速验证某个路径是否可访问:
* * * * * /usr/local/bin/python3 -c "open('/Users/myUser/Projects/test.txt', 'w').write('test')" >>/tmp/perm_test.log 2>&1
等待一分钟后查看/tmp/perm_test.log,如果没有报错,说明该路径Python3可以正常读写。
内容的提问来源于stack exchange,提问作者Adam Smooch

