2017-01-31 79 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 = ...行。 –