2017-01-31 15 views
0

これは私にとって最後の数週間は狂ってしまいました。何が起こっているのかわからないので、私はあなたのすべての脳を選び、誰かが賢明なことが何が起こっているか把握することができますか、少なくとも何が起こっているかを把握するためにトラックに私を取得します。MQTT Pythonはcron経由で起動したときにBashスクリプトを起動できません

それは、少し複雑になるかもしれないと私と一緒に裸をしてください!

MQTT(v3.1.1)を実行している私のいわゆるサーバであるARMデバイスに接続するクライアントスクリプト(Python v2.7)を実行する200の奇妙なARMデバイス(Raspberry Pi 3)があります。

多くの調整や新機能が頻繁に追加されるため、私は先に進んで「更新」機能を作成しました。

Essentually、次のように動作します:

  1. クライアントは、MQTTに接続 - >
  2. クライアントは、クライアントスクリプトのバージョンを実行して送信 - >
  3. 更新がへのリンクが利用可能な場合はサーバーが応答.tar.gzファイル - >
  4. クライアントから.tar.gzファイルをダウンロードして解凍します。
  5. クライアントは、アンパックされたフォルダに標準のbashスクリプト 'update.sh'を実行します。

このbashのファイルは、(インストールする必要があるものによって異なります。)このような「apt-getの更新」または新しいパッケージと新しいスクリプトとして新しいコマンドが含まれてい

更新は、クライアント上に強制され特定のトピックにペイロードを送信することによって、リンク[update/[devicename] 'のようにします。このデバイスはこのトピックにサブスクリプションされており、このペイロードを取得したときにファイルをダウンロードして実行します。

ここでは絶対に変わった部分があります。

完璧に動作します。

完璧なあなたは、なぜあなたは助けが必要ですか?

私はSSH経由スクリプトを実行ONLYときまあ、それは完璧に動作します。 起動時にスクリプトを実行すると、すべて更新が行われます。 msgを更新するようですが、ファイルを取得して解凍したようですが、bashスクリプトの実行に失敗するようです。これはbashスクリプトを実行していない

:私は推測していた場合

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

現在、Pythonは、次のコマンドを使用して、bashスクリプトを実行します。なぜ私は分からない。私が以前に述べたように、SSHで実行すると完璧に動作します。何とかcrontabが再起動時にそれを実行すると、呼び出されません。

それはすべての特権を持っているので、私が知る限り、それはそうではありません。

は、私が試してみた:

まあほとんどすべて私は考えることができます! subprocess.callからos.callまでのさまざまな呼び出し方法は、何も動作していないようでした。私はsudoersの下にユーザを追加しました。またPythonとBashスクリプトの出力を記録しようとしました。 Pythonはエラーを表示せず、Bashログファイルはまったく開始していないようです。

本当に助けになるでしょう!

+0

あなたはジャンFranç[email protected] 'シェル= true'を –

+0

で試すことができ、そのための魅力的な理由なしに、より複雑さと追加の障害ポイントを追加する提案をしないでください。 –

+0

これは単なるコメントであり、答えではありません。それがうまくいかない場合は、バマー。 –

答えて

1

ここにはいくつかの相違点があります。いくつかの可能性が特に高いもの名前を付けるには:

  • cronによって公開された環境が手元にあるスクリプトが正常に動作するために必須で、ユーザーのログインスクリプトによって確立された変数が欠落することができます。

    os.environを作業用と非作業用のケースで比較すると、参考になる可能性があります。

  • sudoコマンドにはTTYが必要な場合があります。

    コマンドのstderrをキャプチャしてエラーでそれを調べると、ここで役に立つ可能性があります。実際にsudoがシェルの実行に成功した場合、/etc/sudoersによってTTYが必要な場合は、シェルによって呼び出された正確なコマンドをキャプチャすることにより、このログをより有益なものにします(set -xシェルオプションを使用)。ない)。

    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

ちなみに、ファイルの先頭に 'PATH = ...'と 'HOME = ...'行を追加することで、それらをあなたのcrontabに直接設定することができます。 –

関連する問題