A execução do programa em .profile impede a inicialização da GUI

1

Eu quero rodar um programa python que monitora o teclado na inicialização / login no meu pi de framboesa.

As tentativas anteriores incluíram tarefas do cron (falha devido à falta de stdin ou stdout).

rc.local também falhou, pois não tem stdin (ficou preso em um loop perpétuo - agora esse foi divertido de escapar)

Por isso, cheguei a colocar meu comando no .profile, e isso parece funcionar bem! O programa funciona exatamente como planejado quando o Pi está ativado mas ...

Quando, em seguida, tento iniciar a GUI por startx , a tela fica preta e completamente falha ao iniciar. Parece ser algo para fazer com o programa Ppython, porque quando eu removê-lo do bash .profile, tudo funciona bem.

Qualquer ajuda seria muito apreciada!

Atualizar

Eu criei um script que também produzia para LEDs (uma sequência simples Vermelho-Amarelo-Verde) e parece que o .profile é executado novamente quando startx é executado? Em caso afirmativo, por que?

Abaixo está meu código .profile e, em seguida, meu programa python; o significado do script python é (eu acredito) que ele roda um loop perpétuo encadeado que é terminado por stdin / keyboard

linhas de perfil

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()
    
por davidhood2 20.10.2016 / 11:29

1 resposta

2

A situação aqui é que você começa na linha de comando e depois chama startx quando estiver pronto. Empiricamente, você acredita que a GUI tenta executar novamente o .profile e o script python não pode sair para que a GUI seja interrompida.

Uma solução que pode valer a pena tentar é definir uma variável de ambiente para garantir que seu código seja executado apenas uma vez:

# 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

Outra opção é chamar o código somente se stdin estiver conectado a um terminal:

# 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

Esta segunda sugestão provavelmente é mais segura, porque ela tratará de programas que fazem login remotamente para executar um serviço (como rsync ou scp ).

Você pode mesclar os dois de forma que o código seja considerado apenas uma vez e só executado se stdin e stdout estiverem conectados a um terminal. (Apenas aninhe as instruções if...fi .)

Fui solicitado a explicar a condição test que protege o código no primeiro exemplo.

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

Isso pode ser escrito em inglês como " Se $DONE_PROFILE estiver vazio Ou $DONE_PROFILE não corresponder a $USER ... ".

A construção ${USER:-unknown} substitui unknown se $USER estiver vazia ou não definida.

Colocar X na frente de ambos os lados da expressão != provavelmente é desnecessário nessa instância, mas é proveniente de uma abordagem de script defensiva. Considere uma variável $A que tenha o valor -z e outra variável $B com o valor apple . Em alguns shells, escrever test "$A" != "$B" seria expandido como test -z != apple , o que é sintaticamente inválido. Prefixar ambos os lados com X resultaria em uma expansão de test X-z != Xapple que é sintaticamente segura.

    
por 20.10.2016 / 12:07