Austauschen von Eingabedaten zwischen Shell-Skripten

Austauschen von Eingabedaten zwischen Shell-Skripten

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 echonoch amdie Zeile ausgeführt wird. Das heißt, das Skript scheint auf etwas zu warten, vielleicht ein Zeilenumbruchzeichen, aber das Hinzufügen von \n, -eArgumenten 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.txtsehen 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).

verwandte Informationen