web-dev-qa-db-ja.com

.profileでプログラムを実行すると、GUIstartxが妨げられます

起動時/ログイン時にキーボードをポーリングしてRaspberryPiに接続するpythonプログラムを実行したいと思います。

以前の試みにはcronジョブが含まれていました(stdinまたはstdoutがないために失敗しました)。

rc.local stdinがないため、失敗しました(永続的なループでスタックしました-今thatはエスケープするのが楽しかったです)

したがって、コマンドを.profileに配置することに到達しました。これは、うまく機能しているようです。プログラムは、Piがオンになっているときに意図したとおりに機能しますbut.. ..

次に、startxでGUIを起動しようとすると、画面が真っ暗になり、完全に起動に失敗します。 bash .profileから削除すると、すべて正常に機能するため、Ppythonプログラムと関係があるようです。

どんな助けでも大歓迎です!

更新

LEDにも出力するスクリプト(単純な赤-黄-緑のシーケンス)を作成しましたが、startxが実行されますか?もしそうなら、なぜですか?

以下は私の.profileコードであり、次に私のpythonプログラム; pythonスクリプトの重要性は(私は信じています)それstdin/keyboardで終了するスレッド化された永続ループを実行します

。profile lines

echo "About to run keyboard polling"; sleep 3
python /home/pi/poll_keyboard.py

poll_keyboard.py

import thread
import time
def input_thread(L):
    key = raw_input()
    L.append(key)
    thread.exit() #Should close thread at end
def do_print():
    L = []
    thread.start_new_thread(input_thread, (L,))
    i = 0
    while True:
        print "Hello World %d" % i
        if L: #If anything has been detected
            break
        i += 1
        time.sleep(0.5)
    return L
key = do_print()
print "Key press detected: %s. Exiting in 2" % key
time.sleep(2)
exit()
2
davidhood2

ここでの状況は、コマンドラインから開始し、準備ができたらstartxを呼び出すことです。経験的に、GUIが.profileを再実行しようとし、pythonスクリプトを終了できないため、GUIがハングする。

試す価値のある解決策の1つは、環境変数を設定して、コードが1回だけ実行されるようにすることです。

# This is .profile
#
if test -z "$DONE_PROFILE" -o "X$DONE_PROFILE" != "X${USER:-unknown}"
then
    # Protected code here will be called only once
    #
    echo "About to run keyboard polling"; sleep 3
    python /home/pi/poll_keyboard.py

    export DONE_PROFILE="${USER:-unknown}"
fi

別のオプションは、stdinが端末に接続されている場合にのみコードを呼び出すことです。

# This is .profile
#
if test -t 0 -a -t 1
then
    # Protected code here will be called only if stdin and stdout is a tty
    #
    echo "About to run keyboard polling"; sleep 3
    python /home/pi/poll_keyboard.py
fi

この2番目の提案は、サービスを実行するためにリモートでログインするプログラム(rsyncscpなど)を処理するため、おそらくより安全です。

コードが1回だけ考慮され、stdinおよびstdoutが端末に接続されている場合にのみ実行されるように、2つをマージすることもできます。 (if...fiステートメントをネストするだけです。)


最初の例のコードを保護するtest条件について説明するように求められました。

if test -z "$DONE_PROFILE" -o "X$DONE_PROFILE" != "X${USER:-unknown}"

これは英語で「$DONE_PROFILEが空の場合、または$DONE_PROFILE$USER... "と一致しない場合」と書くことができます。

${USER:-unknown}が空または設定されていない場合、$USER構文はunknownを置き換えます。

この場合、!=式の両側の前にXを置くことはおそらく不要ですが、これは防御的なスクリプトアプローチによるものです。値が$Aの変数-zと、値がAppleの別の変数$Bについて考えてみます。一部のシェルでは、test "$A" != "$B"を書き込むとtest -z != Appleとして展開され、構文的に無効になります。両側の前にXを付けると、構文的に安全なtest X-z != Xappleが拡張されます。

2
roaima