Eu tenho um script de shell simples para executar no Android adb shell.
while true; do
read var1
echo $var1 > /data/local/tmp/debug.txt
am force-stop $var1
done
Funciona bem se eu inserir um valor no console da instância original do shell. Mas se eu abrir outro shell adb e tentar passar dados para o primeiro processo:
echo "com.package.name" > /proc/XXXX/fd/0
onde XXXX é o pid do primeiro shell, vejo apenas que a string "com.package.name" chega ao primeiro shell read
, mas nem echo
a linha de depuração nem am
a linha são executadas. Esse é o script que parece estar esperando por algo, talvez um caractere de nova linha, mas adicionar \n
, -e
argumento e outras coisas na segunda entrada do shell não ajudou.
Como passo dados corretamente entre scripts de shell?
Responder1
Você está sendo assaltado pelo conceito usual, quetudo em um sistema Linux é um arquivo. Para ilustrar isso, coloquei seus comandos em um arquivo chamado forever
, encontrei o PID do processo e, em seguida,
$ file /proc/25546/fd/*
/proc/25546/fd/0: symbolic link to `/dev/pts/12'
/proc/25546/fd/1: symbolic link to `/dev/pts/12'
/proc/25546/fd/2: symbolic link to `/dev/pts/12'
/proc/25546/fd/255: symbolic link to `/home/me/tmp/forever'
$ file /dev/pts/12
/dev/pts/12: character special
Isso mostra que seus descritores de arquivo 1,2,3 são arquivos de caracteres. Agora, é bem conhecido (ver por exemploesta resposta no Unix e Linux) que:
Dispositivos de caracteres (também chamados de arquivos especiais de caracteres) se comportam como pipes, portas seriais, etc.: escrever ou ler neles é uma ação imediata. Mas o que o motorista faz com os dados éseu próprio negócio. Escrever um byte em um dispositivo de caractere pode fazer com que ele seja exibido na tela, gerado em uma porta serial, convertido em som, ... Ler um byte de um dispositivo pode fazer com que a porta serial espere pela entrada, pode retornar um valor aleatório byte (/dev/urandom), ...
Então você precisa de outra maneira de realizar IPC (= comunicação entre processos).No Unix e no Linux, há tubos nomeadospor esta. Modifique seu script da seguinte maneira:
#!/bin/bash
MYPIPE=/tmp/my_pipe
if [[ ! -p $MYPIPE ]]; then
mkfifo $MYPIPE
fi
while true
do
if read line <$pipe; then
if [[ "$line" == 'quit' ]]; then
break
fi
echo $line >> /tmp/debug.txt
fi
done
echo "I quit"
Inicie o roteiro; de outro tipo de terminal
$ cat > /tmp/my_pipe
My name is
George Washington
....
A partir de um terceiro terminal, usando tail -f /tmp/debug.txt
, você verá o que acabou de digitar no segundo terminal, reaparecendo em /tmp/debug.txt
.
No Android, a situação é um pouco mais complexa, mas você descobriráaquieaquiduas maneiras distintas de contornar o problema de criar pipes nomeados em um dispositivo Android sem root (a primeira é mais simples que a segunda).