OS X 10.10.3 launchctl 权限被拒绝
OS X 10.10.3 launchctl Permission denied
我执行launchctl start com.xxx.xxx.plist
我可以找到 AutoMakeLog.err
和内容 :
Traceback (most recent call last):
File "/Users/xxxx/Downloads/Kevin/auto.py", line 67, in <module>
output = open(file_name, 'w')
IOError: [Errno 13] Permission denied: '2015-04-22-09:15:40.log'
plist 内容:
<array>
<string>/Users/xxxx/Downloads/Kevin/auto.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>30</integer>
<key>Hour</key>
<integer>08</integer>
</dict>
<key>StandardOutPath</key>
<string>/Users/xxxx/Downloads/Kevin/AutoMakeLog.log</string>
<key>StandardErrorPath</key>
<string>/Users/xxx/Downloads/Kevin/AutoMakeLog.err</string>
auto.sh
#!/bin/sh
/usr/bin/python /Users/xxxx/Downloads/Kevin/auto.py
auto.py
file_name = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
file_name += '.log'
output = open(file_name, 'w')
output.writelines(response.text)
output.close()
auto.sh 和 auto.py 有 chomd 777
PS:我直接执行auto.sh没有报错
甚至 用户特定 launchd
OSX 上的作业 也是执行的/
作为当前目录。
由于 auto.py
正在创建一个只有 文件名的文件,没有路径 ,它实际上试图在 /
中创建一个文件] 并由于权限不足而失败。
因此,要么更改为当前用户可以在其中创建文件的目录,要么指定一个显式路径;例如(假设 import os
):
file_name = os.getenv('HOME') + '/' + time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
至于 您如何 运行 您的 python
脚本 直接,而不需要中间人shell 脚本:
在您的 plist 文件中,指定要执行的命令如下:
<key>ProgramArguments</key>
<array>
<string>python</string>
<string>/Users/xxxx/Downloads/Kevin/auto.py</string>
</array>
请注意,您无需为 python
指定路径,因为它在 $PATH
中,而 launchd
运行 是您的作业。
但是,请注意 $PATH
包含的条目 比您在 Terminal
中看到的要少 ,并且值得注意的是 缺失 是 /user/local/bin
;该值为(截至 OSX 10.10.3):
/usr/bin:/bin:/usr/sbin:/sbin
我添加此答案是为了提高可见性,但并未引起此问题的原始问题。
由于 macOS 10.14 Mojave launchd
命令的更改,现在有更多的安全限制。如果您的用户拥有的文件和目录出现 Permission denied
错误,请参阅 Q: How Do I Grant Root Access To User Files in Mojave 以获取可能的修复方法。
我执行launchctl start com.xxx.xxx.plist
我可以找到 AutoMakeLog.err
和内容 :
Traceback (most recent call last):
File "/Users/xxxx/Downloads/Kevin/auto.py", line 67, in <module>
output = open(file_name, 'w')
IOError: [Errno 13] Permission denied: '2015-04-22-09:15:40.log'
plist 内容:
<array>
<string>/Users/xxxx/Downloads/Kevin/auto.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>30</integer>
<key>Hour</key>
<integer>08</integer>
</dict>
<key>StandardOutPath</key>
<string>/Users/xxxx/Downloads/Kevin/AutoMakeLog.log</string>
<key>StandardErrorPath</key>
<string>/Users/xxx/Downloads/Kevin/AutoMakeLog.err</string>
auto.sh
#!/bin/sh
/usr/bin/python /Users/xxxx/Downloads/Kevin/auto.py
auto.py
file_name = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
file_name += '.log'
output = open(file_name, 'w')
output.writelines(response.text)
output.close()
auto.sh 和 auto.py 有 chomd 777
PS:我直接执行auto.sh没有报错
甚至 用户特定 launchd
OSX 上的作业 也是执行的/
作为当前目录。
由于 auto.py
正在创建一个只有 文件名的文件,没有路径 ,它实际上试图在 /
中创建一个文件] 并由于权限不足而失败。
因此,要么更改为当前用户可以在其中创建文件的目录,要么指定一个显式路径;例如(假设 import os
):
file_name = os.getenv('HOME') + '/' + time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
至于 您如何 运行 您的 python
脚本 直接,而不需要中间人shell 脚本:
在您的 plist 文件中,指定要执行的命令如下:
<key>ProgramArguments</key>
<array>
<string>python</string>
<string>/Users/xxxx/Downloads/Kevin/auto.py</string>
</array>
请注意,您无需为 python
指定路径,因为它在 $PATH
中,而 launchd
运行 是您的作业。
但是,请注意 $PATH
包含的条目 比您在 Terminal
中看到的要少 ,并且值得注意的是 缺失 是 /user/local/bin
;该值为(截至 OSX 10.10.3):
/usr/bin:/bin:/usr/sbin:/sbin
我添加此答案是为了提高可见性,但并未引起此问题的原始问题。
由于 macOS 10.14 Mojave launchd
命令的更改,现在有更多的安全限制。如果您的用户拥有的文件和目录出现 Permission denied
错误,请参阅 Q: How Do I Grant Root Access To User Files in Mojave 以获取可能的修复方法。