起動時/ログイン時にキーボードをポーリングして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()
ここでの状況は、コマンドラインから開始し、準備ができたら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番目の提案は、サービスを実行するためにリモートでログインするプログラム(rsync
やscp
など)を処理するため、おそらくより安全です。
コードが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
が拡張されます。