Tengo un script de shell simple para ejecutar en adb shell de Android.
while true; do
read var1
echo $var1 > /data/local/tmp/debug.txt
am force-stop $var1
done
Funciona bien si ingreso un valor en la consola de la instancia de shell original. Pero si abro otro adb shell e intento pasar datos al primer proceso:
echo "com.package.name" > /proc/XXXX/fd/0
donde XXXX es el pid del primer Shell, solo veo que la cadena "com.package.name" llega al primer Shell read
, pero no se ejecuta ni echo
la línea de depuración ni la línea. am
Es decir, el script parece estar esperando algo, tal vez un carácter de nueva línea, pero agregar \n
un -e
argumento y otras cosas en la entrada del segundo shell no ayudó.
¿Cómo paso datos correctamente entre scripts de Shell?
Respuesta1
Estás siendo asaltado por el concepto habitual de quetodo en un sistema Linux es un archivo. Para ilustrar esto, puse sus comandos en un archivo llamado forever
, luego encontré el PID del proceso, luego
$ 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
Esto muestra que los descriptores de archivo 1,2,3 son archivos de caracteres. Ahora bien, es bien sabido (ver por ejemploesta respuesta en Unix y Linux) eso:
Los dispositivos de caracteres (también llamados archivos especiales de caracteres) se comportan como tuberías, puertos serie, etc.: escribirles o leerles es una acción inmediata. Pero lo que hace el conductor con los datos essu propio negocio. Escribir un byte en un dispositivo de caracteres puede hacer que se muestre en la pantalla, se emita en un puerto serie, se convierta en un sonido,... La lectura de un byte desde un dispositivo puede hacer que el puerto serie espere la entrada, puede devolver un mensaje aleatorio. byte (/dev/urandom), ...
Entonces necesita otra forma de realizar IPC (= Comunicación entre procesos).En Unix y en Linux, hay tuberías con nombrepara esto. Modifique su script de la siguiente manera:
#!/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 el guión; desde otro tipo de terminal
$ cat > /tmp/my_pipe
My name is
George Washington
....
Desde una tercera terminal, usando tail -f /tmp/debug.txt
, verás que lo que acabas de escribir en la segunda terminal reaparece desde /tmp/debug.txt
.
En Android, la situación es un poco más compleja, pero encontrarásaquíyaquíHay dos formas distintas de solucionar el problema de crear canalizaciones con nombre en un dispositivo Android no rooteado (la primera es más simple que la segunda).