Trocando dados de entrada entre scripts de shell

2

Eu tenho um script de shell simples para executar no shell adb Android.

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 no primeiro shell read, mas nem depurar echo linha, nem am linha é executada. Esse é o script parece esperar por algo, talvez um caractere de nova linha, mas adicionando \n, -e argumento, e outras coisas na segunda entrada shell não ajudou.

Como faço para passar corretamente os dados entre os scripts de shell?

Stan
fonte
Você está fazendo duas perguntas semelhantes / relacionadas, mas distintas: (1) Como posso trocar dados entre dois scripts ou programas (que eu escrevi), e (2) Como o comando (ou script / programa) “B” pode fornecer entrada para script / programa "A", quando "A" é apenas leitura do terminal / teclado (neste caso, em uma janela diferente) e não está esperando entrada de outro processo (e, portanto, não está fazendo nada especial que lhe permitiria receber entrada de outro processo)? … (Cont.)
Scott
(Cont’d)… A pergunta 1 é razoavelmente ampla; Resposta de MariusMatutiae é um bom começo para responder. Question2 é difícil. Em geral, é impossível. Se fosse fácil, seria uma fraqueza na segurança, por isso foi dificultada, e cada vez mais ao longo dos anos - algumas soluções que funcionaram cinco ou mais anos atrás podem não funcionar em sistemas modernos. … (Cont.)
Scott
(Cont’d) ... Esta é uma possível duplicação de Como redirecionar para stdin de um shell bash em execução? . (Eu não posso votar para fechar porque tem uma recompensa aberta.) ... (Cont.)
Scott
@ Scott, estou apenas fazendo a pergunta sobre a tarefa concreta. Claro que você é livre para dissecá-lo para algumas subtarefas como desejar. A maioria de suas referências parece irrelevante, porque eu estou limitado a shell adb android. Mas obrigada mesmo assim.
Stan

Respostas:

1

Você está sendo assaltado pelo conceito usual, que tudo em um sistema Linux é um arquivo . Para ilustrar isso, coloquei seus comandos em um arquivo chamado forever, em seguida, encontrou o PID do processo, então

$ 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 caractere. Agora, é bem conhecido (veja por exemplo esta resposta no Unix e no Linux ) naquela:

Os dispositivos de caracteres (também chamados de arquivos especiais de caracteres) se comportam como pipes, portas seriais, etc: escrever ou ler para eles é uma ação imediata. Mas o que o motorista faz com os dados é seu próprio negócio . A gravação de um byte em um dispositivo de caractere pode fazer com que ele seja exibido na tela, saída em uma porta serial, convertido em um som, ... Ler um byte de um dispositivo pode fazer com que a porta serial espere pela entrada, pode retornar um aleatório byte (/ dev / urandom), ...

Então você precisa de outra maneira de realizar o IPC (= Inter Process Communication). No Unix e no Linux , há pipes nomeados por 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 script; de outro tipo de terminal

 $ cat > /tmp/my_pipe
   My name is 
   George Washington 
    ....

De um terceiro terminal, usando tail -f /tmp/debug.txt, você verá o que acabou de digitar no segundo terminal, reaparecer /tmp/debug.txt.

No Android , a situação é um pouco mais complexa, mas você vai encontrar Aqui e Aqui duas maneiras distintas em torno do problema de criar pipes nomeados em um dispositivo Android não enraizado (o primeiro é mais simples que o segundo).

MariusMatutiae
fonte
1
não deveria ser cat > /tmp/my_pipe ao invés de cat /tmp/my_pipe? Ou estou apenas sentindo falta de algo diferente neste ambiente?
ecube
@ dma1324 Não, você me pegou. Você está perfeitamente certo, eu corrigi. Obrigado por localizá-lo.
MariusMatutiae