Ich habe ein Wrapper-Script, das eine Reihe von Filedeskriptoren öffnet und beschreibt oder liest: &3 &4 &6 und &7.
Nun habe ich bemerkt, daß ich Probleme bekomme, wenn mein Script andere Scripte (oder eine andere Instanz von sich selbst) aufruft. bash vererbt die Filedescriptoren an aufgerufene Scripte. Wenn diese ihrerseits die gleichen Filedescriptoren öffnen, beschreiben und schließen, gibt es Chaos.
Kann ich bash anweisen, Filedescriptoren *nicht* weiterzureichen? Bei "help set" habe ich nichts gefunden.
[gelöst] bash: file descriptor *nicht* vererben
[gelöst] bash: file descriptor *nicht* vererben
Zuletzt geändert von MartinV am 14.05.2018 22:40:51, insgesamt 1-mal geändert.
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.
-
- Beiträge: 507
- Registriert: 30.12.2016 23:48:51
Re: bash: file descriptor *nicht* vererben
Das ist generell nicht möglich. Da müsstest schon beispielsweise ein C-Programm schreiben, um dieses Verhalten unmittelbar zu ändern. Nur warum musst überhaupt soviele File-Descriptors offen halten? Das ist nicht unbedingt typisch und könnte ggf. auch anders gelöst werden. Zumindest kannst über die Bash hunderte von File-Descriptors nutzen, womit eigentlich genug Spielraum haben solltest. Andererseits kannst dein Shellscript auch mal posten.
Re: bash: file descriptor *nicht* vererben
Nein, das wird vererbt. Du kannst aber im aufgerufenen Skript die FDs gefahrlos entfernen, ohne dass es Konsequenzen für das aufrufende Skript hat. Liste über /proc/$$/fd oder bash-spezifisch /proc/${BASHPID}/fd.MartinV hat geschrieben:14.05.2018 16:42:42Kann ich bash anweisen, Filedescriptoren *nicht* weiterzureichen?
Re: bash: file descriptor *nicht* vererben
Das Script hat ein paar tausend Zeilen . Du findest es hier: https://github.com/mviereck/x11dockerbreakthewall hat geschrieben:14.05.2018 17:38:16Andererseits kannst dein Shellscript auch mal posten
Ein Problem ist, das ich nicht vorhersehen kann, welche Filedescriptoren ein aufgerufenes Programm bzw. Script möglicherweise nutzt. Mein Script ist ein Wrapper, dem ein beliebiges anderes Programm als Argument übergeben werden kann, das dann gestartet wird.breakthewall hat geschrieben:14.05.2018 17:38:16Zumindest kannst über die Bash hunderte von File-Descriptors nutzen, womit eigentlich genug Spielraum haben solltest.
Ich habe gerade für den Fall, daß mein Script sich selbst startet, das Problem beheben können. (Eine interne Prüfung, ob ein Logfile-Descriptor schon offen ist, war falsch).
Gute Nachricht: Öffnet ein aufgerufenes Script die gleiche Filedeskriptor-Nummer, kann es sie verwenden, ohne den Filedeskriptor des Wrapper-Scriptes zu beeinflussen. Das Tochterskript kann nur nicht mehr in den Deskriptor des Wrappers hineinschreiben.
(Edit: Zeitüberschneidung, das ist das, was auch tobo schreibt.)
Das Problem hält sich also in Grenzen. Ein sauberes Tochterskript wird seine eigenen Deskriptoren öffnen, bevor es hineinschreibt. Sollte es nicht so sauber sein, beschmutzt es in diesem Fall nur Logdateien und Terminalausgabe des Wrappers, macht aber nichts kaputt.
Würde ich wichtigere Daten umleiten, hätte ich allerdings ein echtes Problem.
Edit: Eine Alternative sind named pipes, die ich mit mkfifo erzeugen kann. Eine sichere Lösung bietet das aber auch nicht, da jedes Programm dort hineinschreiben könnte. Aber zumindest würde es vermutlich nicht in der Erbschaft auftauchen.
Zuletzt geändert von MartinV am 15.05.2018 09:31:43, insgesamt 1-mal geändert.
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.
Re: bash: file descriptor *nicht* vererben
Danke, tobo! Das hat mich letzlich zu einer Lösung geführt.tobo hat geschrieben:14.05.2018 18:02:57Du kannst aber im aufgerufenen Skript die FDs gefahrlos entfernen, ohne dass es Konsequenzen für das aufrufende Skript hat. Liste über /proc/$$/fd oder bash-spezifisch /proc/${BASHPID}/fd.
Ich erzeuge im Wrapper-Skript ein weiteres Skript, das erst die Filedeskriptoren schließt, bevor es das gewünschte Programm startet.
Direktes Löschen mit rm war nicht möglich mangels Schreibrechten in /proc/$$. Stattdessen regulär schließen mit "exec >&3- >&4- >&6- >&7-".
So bleiben dem Wrapper die Filedeskriptoren erhalten, das letztendlich gestartete Programm bekommt sie aber nicht zu sehen.
Kurzform als Einzeiler: exec in einer Subshell. Dadurch wird nur die Subshell ersetzt, nicht das Hauptskript:
Code: Alles auswählen
(exec >&3- >&4- >&6- >&7- programm)
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.