我是一个完全的初学者,想尝试一下 Python 的 check_output 函数。
我有一个基于用户的 cron 作业,它会打开一个 bash 文件,该文件又会打开一个要在启动时执行的 Python 脚本。我正在无头运行我的 Raspberry pi,但如果我想通过 SSH 连接,我会使用屏幕来检查 Python 进程。
我的用户 crontab 看起来像这样,并且启动非常顺利,因为 Python 脚本实际上已经启动并且几乎可以正常工作。
@reboot sleep 30 && sh /home/pi/launcher.sh >>/home/pi/logs/cronlog 2>&1
这是启动屏幕然后启动 Python 脚本的 bash 文件
#!/bin/sh
screen -h 500 -S Telegram -d -m /usr/bin/python /home/pi/telegram/bot2.py
这是有问题的 Python 文件。我可以正常启动它并验证它是否正常工作。但 check_output 给我一个错误。
import os
import sys
import time
import telepot
from telepot.loop import MessageLoop
from subprocess import call
from subprocess import check_output
from subprocess import CalledProcessError
print 'Hello'
def handle(msg):
chat_id = msg['chat']['id']
command = msg['text']
print 'Got command: %s' % command
if command == 'Status':
try:
result = check_output(['service','hostapd','status'])
except CalledProcessError as exc:
result = exc.output
MessageLoop(bot, handle).run_as_thread()
print 'I am listening ...'
while 1:
time.sleep(10)
这是我得到的错误。有趣的是,简单的调用过程不会给我这个错误并且运行正常。
Got command: Status
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/telepot/loop.py", line 37, in run_forever
self._handle(msg)
File "/home/pi/telegram/bot2.py", line 31, in handle
result = check_output(['service','hostapd','status'])
File "/usr/lib/python2.7/subprocess.py", line 212, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 390, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1024, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
我希望有人能帮助我。我感觉这与启动时的权限或环境有关。
非常重要的一点是,当我手动进入并在登录时自行启动 bash 文件时,整个过程就像魔法一样运行。
编辑:我进行了一些探索,现在收到了不同的错误:
Got command: Status
/bin/sh: 1: service: not found
我改变了命令在 Python 脚本中
result = check_output(["service hostapd status"], shell=True )
答案1
我想到了 !!!:
它起作用的原因仍然不清楚,但它已经通过经验证明是有效的,所以我很高兴。
修复方法是将 check_output 命令从原来的
result = check_output(['service','hostapd','status'])
现在的工作
result = check_output(["/usr/sbin/service hostapd status"], shell=True )
首先,该shell=True
部件是必需的,然后通过快速搜索which service
找到了服务“service”的位置。之后,phython 很满意。
这整个事情最奇怪的是,我在同一 phython 脚本的后半部分中使用的表达式没有遇到任何问题。
call(["sudo","service","hostapd","start"])
编辑:现在我研究了这个来写答案,我意识到调用函数有一个小的“sudo”,而我的 check_output 没有。
编辑:所以我当然回去并修改了 check_output 函数,使其也有一个简单的 sudo,并且它完全没有 shell=True 的麻烦。
最终解决方案对我有用:
改变
result = check_output(['service','hostapd','status'])
到
result = check_output(['sudo','service','hostapd','status'])