Isso não funciona em muitos níveis. Principalmente, o bash não é muito bom para programação multi-threaded. Mas se você for fazer assim, você tem que perceber duas coisas: (1) para que o seu "thread" de leitura de chave funcione, ele tem que ter acesso exclusivo ao tty. (2) Quando você coloca um processo em segundo plano, ele irá naturalmente copiar stdin do processo atual 'tty. (3) Normalmente, o shell detecta isso e interrompe o processo em segundo plano.
Only foreground processes are allowed to read from or, if the user so specifies with stty tostop, write to the terminal. Background processes which attempt to read from (write to when stty tostop is in effect) the terminal are sent a SIGTTIN (SIGTTOU) signal by the kernel's terminal driver, which, unless caught, suspends the process.
Você pode ver isso aqui:
otheus@otheus-VirtualBox ~ $ ( while true; read x; do echo $x; done; ) &
[1] 2841
otheus@otheus-VirtualBox ~ $
[1]+ Stopped ( while true; read x; do
echo $x;
done )
Portanto, o processo de leitura de tty deve estar em primeiro plano. O background pode fazer o "trabalho", mas certifique-se de fechar o stdin primeiro: <&-
Para parar o processo "trabalhador", você terá que conhecer o seu pid. Para fazer isso, você precisa ativar o controle de tarefas dentro de um script (está desativado por padrão). set -m
faz isso. Inicie e mate %-
após o pressionamento de tecla. Você pode querer certificar-se de que o loop de pressionamento de tecla termina quando o trabalhador faz. Você faz seu segmento de monitor de chave:
start_worker &
while jobs %- &>/dev/null; do
read -n 1 -s -t 1 key
# test key
if [[ $key == q ]]; then
kill -1 %-
break
fi
fi
wait
A condição while testa se o trabalho ainda está sendo executado / reconhecido. Quando terminar, os trabalhos retornarão false e o loop será encerrado. O comando de leitura agora também expira após 1 segundo. Finalmente, depois que o loop sair, espere para ter certeza de que o trabalho está "limpo". (Se você tiver outros trabalhos em execução, isso irá parar aqui.)
A outra coisa é: o que você está tentando realizar é inerentemente perigoso. A mistura de acesso root e bash scripting é perigosa . Existem alguns tópicos para abordar aqui, como o que acontece quando o usuário acessa Control-C ou Ctl-Z.
Por último, não tenho certeza se você pode misturar o segmento de trabalho com su
como no seu exemplo. Quando o su é executado, ele alterará o tty atual para o root, impedindo que o thread de trabalho seja enviado para ele.