Ich verstehe, dass File Descriptor (oder File Handler) eine Datei-E / A-Technik in Linux-Systemen ist.
Ich weiß auch, dass jeder Prozess 3 Standard-Streams hat (nämlich stdin, stdout und stderr), die durch Dateien mit Deskriptoren von 0 bis 3 dargestellt werden.
Ich stelle jedoch fest, dass alle Prozesse, mit denen ich untersucht lsof -p <pid>
habe, einen zusätzlichen Dateideskriptor 255
mit Leseberechtigung haben.
Aus dieser Antwort habe ich erfahren, dass diese Funktion spezifisch für die Bash-Shell ist. Sowohl die Antwort als auch die Quelle, auf die verwiesen wird, haben jedoch nicht wirklich erklärt, wofür dieser Dateideskriptor gedacht ist.
Meine Frage:
- Wofür ist der 255-Dateideskriptor?
- Kann ich es in meinem Bash-Skript verwenden oder handelt es sich nur um einen internen Arbeitsmechanismus, der nicht manuell verwendet / manipuliert werden soll?
bash
file-descriptors
Tran Triet
quelle
quelle
Antworten:
Zum letzten Teil Ihrer Frage:
kann ich es benutzen?
Von
man bash
:Wenn Sie also die Erstellung eines neuen fd mit dieser Nummer verwenden möchten, lautet die Antwort nein.
Wenn du meinst, benutze als: "schreibe auf diesen fd":
Oder daraus zu lesen:
Die Antwort ist ja.
Aber wahrscheinlich sollte es besser (unabhängig von der Shell) sein, um
/dev/tty
auf die zuzugreifentty
.Wofür ist der Dateideskriptor 255?
Als alternative Verbindung zum tty für den Fall, dass fd 1 (
/dev/stdout
) und fd 0 (/dev/stdin
) blockiert werden.Mehr Details .
Andere Shells verwenden möglicherweise eine andere Nummer (z. B. 10 in zsh).
Aus der Mailingliste :
quelle
dd bs=1 | bash -i -c 'sleep .1; ls -l /proc/$$/fd' 2>/tmp/err | tee /tmp/out
. Außerdem geht es bei diesem Kommentar aus der Mailingliste darum, wann er ausgeführtbash
wirdbash scriptfile
(255
in diesem Fall ist das offene Handle fürscriptfile
- und in diesem Fallls -l /proc/pid/fd
wird er sehr überzeugend gedruckt255 -> scriptfile
;-)), und nicht darum, wann er interaktiv ausgeführt wird./dev/tty
, nicht von fd 0 oder fd 1 c) wenn fds 0, 1 oder 2 get "blockiert", bash wird nicht verwenden , dass 255 fd als Alternative für Lesen von Eingaben vom Benutzer oder zum Schreiben von Befehlsausgaben, Eingabeaufforderungen, Fehlermeldungen usw.Dieser
255
Dateideskriptor ist ein offenes Handle für das steuernde tty und wird nur verwendet, wenn erbash
im interaktiven Modus ausgeführt wird.Sie können das
stderr
in der Haupt-Shell umleiten , während die Jobsteuerung weiterhin funktioniert (dh Prozesse mit ^ C beenden, mit ^ Z unterbrechen usw.).Beispiel:
Wenn Sie dies in einer Shell wie versuchen
ksh93
, die einfach den Dateideskriptor 2 als Referenz für das steuernde Terminal verwendet, wird dersleep
Prozess immun gegen ^ C und ^ Z und muss aus einem anderen Fenster / einer anderen Sitzung beendet werden. Dies liegt daran, dass die Shell die Prozessgruppe von nichtsleep
als Vordergrundgruppe im Terminal mit festlegen kanntcsetgrp()
, da der Dateideskriptor 2 nicht mehr auf das Terminal zeigt.Dies ist nicht
bash
spezifisch, es wird auch indash
und verwendetzsh
, nur dass der Deskriptor nicht so hoch verschoben wird (normalerweise sind es 10).zsh
wird dieses fd auch verwenden, um Eingabeaufforderungen und Benutzereingaben wiederzugeben, sodass einfach Folgendes funktioniert:Es hat nichts mit den
bash
Dateihandles zu tun, die beim Lesen von Skripten und beim Einrichten von Pipes verwendet werden (die mit derselben Funktion ebenfalls aus dem Weg geräumt werden -move_to_high_fd()
), wie dies in anderen Antworten und Kommentaren vorgeschlagen wurde.bash
verwendet eine so große Anzahl, um zu ermöglichen, dass fds größer sind als9
bei In-Shell-Umleitungen (z. B.exec 87<filename
); Das wird in anderen Shells nicht unterstützt.Sie können dieses Dateihandle selbst verwenden, aber es macht wenig Sinn, dies zu tun, da Sie in jedem Befehl mit ein Handle für dasselbe steuernde Terminal erhalten können
... < /dev/tty
.Quellcode-Analyse von Bash :
In
bash
wird der Dateideskriptor des steuernden Terminals in dershell_tty
Variablen gespeichert . Wenn die Shell interaktiv ist, wird diese Variable (beim Start oder nach einer fehlgeschlagenen Ausführung)jobs.c:initialize_job_control()
durch Dup'ing vonstderr
(wennstderr
an ein Terminal angeschlossen) oder durch direktes Öffnen/dev/tty
initialisiert und dann erneut auf einen höheren fd dup'ed mitgeneral.c:move_to_high_fd()
:Wenn
shell_tty
nicht bereits die steuernde tty ist, dann wird es so gemacht:shell_tty
ist dann daran gewöhntHolen und setzen Sie die Vordergrundprozessgruppe mit
tc[sg]etpgrp
injobs.c:maybe_give_terminal_to()
,jobs.c:set_job_control()
undjobs.c:give_terminal_to()
termios(3)
Holen Sie sich und setzen Sie die Parameter injobs.c:get_tty_state()
undjobs.c:set_tty_state()
Holen Sie sich die Größe des Terminalfensters mit
ioctl(TIOCGWINSZ)
inlib/sh/winsize.c:get_new_window_size()
.move_to_high_fd()
wird im Allgemeinen mit allen temporären Dateideskriptoren verwendet, die vonbash
(Skriptdateien, Pipes usw.) verwendet werden, daher die Verwirrung in den meisten Kommentaren, die bei Google-Suchanfragen häufig vorkommen.Die intern von
bash
einschließlich verwendeten Dateideskriptorenshell_tty
sind alle auf close-on-exec eingestellt, damit sie nicht an Befehle weitergegeben werden.quelle