好吧所以这让我疯了几个星期,我不知道发生了什么事情,所以我希望能够挑选你所有的大脑,看看是否有人更聪明可以弄清楚发生了什么或者至少让我走上正轨,弄清楚发生了什么。
我有200多个ARM设备(Raspberry Pi 3)运行客户端脚本(Python v2.7),连接到1个ARM设备,即我所谓的服务器,运行MQTT(v3.1.1)。
由于经常添加大量调整和新功能,我继续创建了“更新”功能。
此时,它的工作原理如下:
- 客户端连接到MQTT - >
- 客户端发送正在运行的客户端脚本版本 - >
- 如果更新可用,并且链接指向.tar.gz文件 - >
,则服务器会响应- 客户端下载.tar.gz文件并解压缩。
- 客户端在解包文件夹中运行标准bash脚本'update.sh'。
醇>
此bash文件包含新命令,例如“apt-get update”或新软件包以及新脚本(取决于需要安装的内容。)
通过向特定主题发送有效负载(例如带有链接的“update / [devicename]”),强制更新客户端。设备已订阅此主题,并在获取此有效负载时下载并运行该文件。
现在这是绝对奇怪的部分!
它完美无缺!
完美的你说,那你为什么需要帮助?
当我通过SSH运行脚本时,它完美地运行 ONLY 。 如果我在启动时运行脚本,除了更新之外一切正常。它似乎得到了msg更新,它似乎获取文件并解压缩它,但它似乎无法运行bash脚本。
目前,Python使用以下命令运行bash脚本:
call(["sudo", "sh", "/update/update.sh"])
如果我不得不猜测:
它没有运行bash脚本。我不知道为什么。正如我之前提到的,当我通过SSH运行它时,它运行得很完美,当crontab在重启时运行它时,它将不会被调用。
它确实拥有所有权限,据我所知,这不是它。
我试过了:
我几乎可以想到的一切!不同的调用方法,从subprocess.call到os.call,似乎没什么用。我还在sudoers下添加了用户,我也尝试记录Python和Bash脚本的输出。 Python没有显示错误,Bash日志文件似乎根本没有启动。
任何帮助都会得到真正的赞赏!
答案 0 :(得分:1)
这里有几个可能的差异。仅举几例:
cron
公开的环境可能缺少用户登录脚本建立的变量,这些变量对于手头脚本的成功操作是必需的。
比较工作和非工作案例之间的os.environ
可能会提供信息。
您的sudo
命令可能需要TTY。
捕获你的命令的stderr,并在出错时检查它,在这里可能会有所帮助。使用set -x
shell选项,如下所示,通过捕获shell调用的确切命令(如果实际上sudo
成功执行shell),将使此日志更具信息性;在TTY的情况下您的/etc/sudoers
需要,但可能不是。
cmd = ['sudo', 'sh', '-x', '/update/update.sh']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(output, err) = p.communicate()
if p.returncode != 0:
# TODO: LOG THE CONTENTS OF err SOMEWHERE YOU CAN REVIEW THEM!
raise subprocess.CalledProcessError(p.returncode, err)