Ich habe ein einfaches Skript geschrieben, echo
dessen PID:
#/bin/bash
while true; do
echo $$;
sleep 0.5;
done
Ich führe das Skript (es steht 3844
immer wieder) in einem Terminal aus und versuche, tail
den Dateideskriptor in einem anderen zu verwenden:
$ tail -f /proc/3844/fd/1
Es druckt nichts auf den Bildschirm und hängt bis ^c
. Warum?
Außerdem sind alle STD-Dateideskriptoren (IN / OUT / ERR) mit denselben Punkten verknüpft:
$ ls -l /proc/3844/fd/
total 0
lrwx------ 1 mg mg 64 sie 29 13:42 0 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 1 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 2 -> /dev/pts/14
lr-x------ 1 mg mg 64 sie 29 13:42 254 -> /home/user/test.sh
lrwx------ 1 mg mg 64 sie 29 13:42 255 -> /dev/pts/14
Ist das normal?
Ausführen von Ubuntu GNOME 14.04.
Wenn Sie der Meinung sind, dass diese Frage zu SO oder SU anstelle von UL gehört, sagen Sie es.
linux
bash
proc
file-descriptors
cprn
quelle
quelle
Antworten:
Machen Sie ein
strace
austail -f
, es erklärt alles. Der interessante Teil:Was es macht? Es richtet einen
inotify
Handler für die Datei ein und wartet dann, bis mit dieser Datei etwas passiert. Wenn der Kerneltail
über diesen inotify-Handler sagt , dass die Datei geändert wurde (normalerweise wurde sie angehängt), danntail
1) sucht 2) liest die Änderungen 3) schreibt sie auf den Bildschirm./proc/3844/fd/1
Auf Ihrem System befindet sich eine symbolische Verknüpfung zu/dev/pts/14
einem Zeichengerät. Es gibt keine "Speicherkarte", auf die dadurch zugegriffen werden könnte. Somit gibt es nichts, dessen Änderungen an der inotify signiert werden könnten, da es keine Festplatte oder keinen Speicherbereich gibt, auf die damit zugegriffen werden könnte.Dieses Zeichengerät ist ein virtuelles Terminal, das praktisch so funktioniert, als wäre es ein Netzwerk-Socket. Programme, die auf diesem virtuellen Terminal ausgeführt werden, stellen eine Verbindung zu diesem Gerät her (so als ob Sie über einen TCP-Port telnetiert hätten) und schreiben, in was sie schreiben möchten. Es gibt auch komplexere Dinge, zum Beispiel das Sperren des Bildschirms, Terminalsteuerungssequenzen und dergleichen, die normalerweise von
ioctl()
Anrufen erledigt werden .Ich denke, Sie möchten sich irgendwie ein virtuelles Terminal ansehen. Es kann unter Linux durchgeführt werden, ist aber nicht so einfach, es benötigt einige Netzwerk-Proxy-ähnliche Funktionen und ein wenig knifflige Verwendung dieser
ioctl()
Aufrufe. Aber es gibt Werkzeuge, die das können.Derzeit kann ich mich nicht erinnern, welches Debian-Paket das Tool für dieses Ziel hat, aber mit ein wenig googeln könnte man das wahrscheinlich leicht finden.
Erweiterung: Wie hier bei @Jajesh erwähnt (gib ihm eine +1, wenn du mir gegeben hast), heißt das Tool
watch
.Erweiterung # 2: @kelnos erwähnt, eine einfache
cat /dev/pts/14
waren auch genug. Ich habe das versucht und ja, es hat funktioniert, aber nicht richtig. Ich habe nicht viel damit experimentiert, aber es scheint mir, als ob eine Ausgabe, die in dieses virtuelle Terminal geht, entweder an dencat
Befehl oder an seinen ursprünglichen Ort geht und niemals an beide. Aber es ist nicht sicher.quelle
tail
ist richtig (das inotify watch bit), aber er ist insofern falsch, als es eigentlich sehr einfach ist, das zu tun, was man will: einfach verwendencat
statttail
.cat
funktioniert auch bei mir nicht, es hängt genauso wie der Schwanz und alles was ich tun kann istctrl+c
.echo $$
,echo $$ >> foo
jetzt gibt es eine Datei und der Prozess öffnet sie und hängt sie alle 0,5 Sekunden an. Ich kann immer noch nicht über den Dateideskriptor darauf zugreifen und alle Dateideskriptoren in/proc/$pid/fd/
(aber 254, die auf dastest.sh
Skript selbst verweisen) verlinken auf/dev/pts/14
. Wie schreibt Bash-Zugrifffoo
darauf?Dateien in
/dev/pts
sind keine regulären Dateien, sondern Handles für virtuelle Terminals. Einpts
Verhalten zum Lesen und Schreiben ist nicht symmetrisch (das heißt, was dort geschrieben ist, kann später daraus gelesen werden, wie eine reguläre Datei oder ein FIFO / eine Pipe), sondern wird durch den Prozess vermittelt, der das virtuelle Terminal erstellt hat: Einige gängige sind xterm oder ssh oder agetty oder screen. Der Steuerungsprozess sendet normalerweise Tastendrücke an Prozesse, die diepts
Datei lesen , und rendert auf dem Bildschirm, was sie auf die Datei schreibenpts
.So
tail -f /dev/pts/14
werden die Tasten gedruckt, die Sie auf das Terminal tippen, von dem aus Sie Ihr Skript gestartet haben, und wenn Sie dies tun, wirdecho meh > /dev/pts/14
diemeh
Nachricht im Terminal angezeigt.quelle
tail -f /dev/pts/14
Druckt nicht die Tasten, die ich auf diesem Terminal tippe. Es ist jedoch eine interessante Antwort. Vielen Dank.Vor einiger Zeit habe ich eine Art Problemumgehung gefunden , die manchmal die Notwendigkeit beantwortet, zu überprüfen, was an STDOUT ausgegeben wird, vorausgesetzt, Sie haben einen
pid
Teil des Prozesses und können die Augen unfreundlicher Ergebnisse entblößen:quelle
Ich denke, dafür müssen Sie die Ausgabe beobachten, anstatt sie zu verfolgen.
Hoffe das ist was du brauchst.
quelle
watch
. Ich versuche, die Ausgabe des bereits ausgeführten Prozesses zu überprüfen, waswatch
nicht hilft.