2017-01-31 146 views
0

好吧,这让我在过去的几周内疯狂,我不知道发生了什么,所以我希望能够挑选出所有的大脑,看看是否更聪明的人可以弄清楚发生了什么事情,或者至少让我走上正确的道路来弄清楚发生了什么。MQTT Python无法在通过cron调用时启动Bash脚本

这就是说,请裸露我可能会有点复杂!

我有200多个运行客户端脚本(Python v2.7)的ARM设备(Raspberry Pi 3's)连接到运行MQTT(v3.1.1)的1 ARM设备,我所谓的服务器。

由于频繁添加了许多调整和新功能,我继续创建“更新”功能。

Essentually,其工作原理如下:

  1. 客户端连接到MQTT - >
  2. 客户端发送运行的客户端脚本版本 - >
  3. 如果更新可用的链接到服务器响应.tar.gz文件 - >
  4. 客户端下载.tar.gz文件并将其解压缩。
  5. 客户端在解压后的文件夹中运行标准bash脚本'update.sh'。

此bash的文件包含新的命令,如“apt-get的更新”或新的包和一个新的脚本(根据需要安装的东西。)

更新是在客户端强制通过发送一个有效载荷到一个特定的主题,比如'update/[devicename]'链接。该设备是以这个主题为基础的,并且会在获得该有效载荷时下载并运行该文件。

现在这里是绝对怪异的部分!

它工作完美!

完美的你说,那你为什么需要帮助?

那么,它可以完美运行ONLY当我运行通过SSH的脚本。 如果我在启动时运行该脚本,除了更新之外,一切都可以运行。它似乎得到更新的味精,它似乎得到的文件和解压缩,但它似乎无法运行bash脚本。如果我猜

call(["sudo", "sh", "/update/update.sh"]) 

它不运行bash脚本

目前,Python的运行具有以下命令的bash脚本。我不知道为什么。正如我前面提到的,当我通过SSH运行它时它工作得很好,不知何故,当crontab在重新启动时运行它时,它不会被调用。

它确实拥有所有的特权,所以据我所知,事实并非如此。

我已经试过:

好了几乎所有我能想到的!不同的调用方法,从subprocess.call到os.call,似乎没有任何工作。我还在sudoers下添加了用户,并且还尝试记录Python和Bash脚本的输出。 Python显示没有错误,Bash日志文件似乎根本没有启动。

任何帮助都会真的得到满足!

+0

你可以用'壳= TRUE' –

+0

@让FrançoisFabre尝试,请不要让增加更多的复杂性和额外的故障点,而一个引人注目的原因相同的建议。 –

+0

这只是一个评论,而不是一个答案。如果它不起作用,那么很无聊。 –

回答

1

这里有几种可能的差异。仅举几例特别容易的:

  • 通过cron暴露可能是通过用户的登录脚本,是强制性手头的剧本的成功运作建立失踪变量的环境。

    比较os.environ之间的工作和非工作情况可能是信息。

  • 您的sudo命令可能需要TTY。

    捕获您的命令的错误,并检查错误,这可能会有所帮助。如下所示,使用外壳选项set -x,将通过捕获shell调用的确切命令,使该日志更加丰富(如果实际上sudo成功执行了shell;如果/etc/sudoers需要TTY,它可能会不)。

    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) 
    
+0

@ user5740843,很高兴你的问题得到了解决 - 任何反馈意见的机会如何,或者究竟是什么问题? –

+1

os.environ似乎与cron和普通用户不同。我已经设置了os.environ ['PATH']和os.environ ['HOME'],它能够正常工作。再次感谢! – user5740843

+0

顺便提一句,你可以直接在你的crontab中设置这些文件,在文件的顶部加入PATH = ...和HOME = ...行。 –