Ich habe ein einfaches Shell-Skript zum Ausführen in der Android-ADB-Shell.
while true; do
read var1
echo $var1 > /data/local/tmp/debug.txt
am force-stop $var1
done
Es funktioniert einwandfrei, wenn ich einen Wert in die Konsole der ursprünglichen Shell-Instanz eingebe. Aber wenn ich eine andere ADB-Shell öffne und versuche, Daten an den ersten Prozess zu übergeben:
echo "com.package.name" > /proc/XXXX/fd/0
wobei XXXX die PID der ersten Shell ist, sehe ich nur, dass die Zeichenfolge „com.package.name“ in der ersten Shell ankommt read
, aber weder die Debugzeile echo
noch am
die Zeile ausgeführt wird. Das heißt, das Skript scheint auf etwas zu warten, vielleicht ein Zeilenumbruchzeichen, aber das Hinzufügen von \n
, -e
Argumenten und anderen Dingen in die zweite Shell-Eingabe hat nicht geholfen.
Wie übergebe ich Daten ordnungsgemäß zwischen Shell-Skripten?
Antwort1
Sie werden von dem üblichen Konzept aufgehalten, dassalles in einem Linux-System ist eine Datei. Um dies zu veranschaulichen, habe ich Ihre Befehle in eine Datei namens gepackt forever
, dann die PID des Prozesses gefunden und dann
$ 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
Dies zeigt, dass Ihre Dateideskriptoren 1,2,3 Zeichendateien sind. Nun ist es allgemein bekannt (siehe zum Beispieldiese Antwort zu Unix und Linux) Das:
Zeichengeräte (auch Zeichen-Spezialdateien genannt) verhalten sich wie Pipes, serielle Schnittstellen usw.: Das Schreiben oder Lesen von ihnen ist eine unmittelbare Aktion. Aber was der Treiber mit den Daten macht, istsein eigenes Geschäft. Das Schreiben eines Bytes auf ein Zeichengerät kann dazu führen, dass es auf dem Bildschirm angezeigt, über eine serielle Schnittstelle ausgegeben oder in einen Ton umgewandelt wird usw. Das Lesen eines Bytes von einem Gerät kann dazu führen, dass die serielle Schnittstelle auf eine Eingabe wartet, ein zufälliges Byte (/dev/urandom) zurückgegeben wird usw.
Sie benötigen also eine andere Möglichkeit, IPC (= Inter Process Communication) durchzuführen.Unter Unix und Linux, es gibt Benannte Pipesdafür. Passen Sie Ihr Skript wie folgt an:
#!/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"
Starten Sie das Skript; geben Sie von einem anderen Terminal aus ein
$ cat > /tmp/my_pipe
My name is
George Washington
....
Von einem dritten Terminal aus tail -f /tmp/debug.txt
sehen Sie mithilfe von , dass das, was Sie gerade in das zweite Terminal eingegeben haben, erneut angezeigt wird /tmp/debug.txt
.
Auf Androidist die Situation etwas komplexer, aber Sie werden feststellenHierUndHierzwei verschiedene Möglichkeiten, das Problem der Erstellung benannter Pipes auf einem nicht gerooteten Android-Gerät zu umgehen (die erste ist einfacher als die zweite).