Troca de dados de entrada entre scripts shell

Troca de dados de entrada entre scripts shell

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 echoa linha de depuração nem ama linha são executadas. Esse é o script que parece estar esperando por algo, talvez um caractere de nova linha, mas adicionar \n, -eargumento 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).

informação relacionada