GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Dateideskriptoren und Shell-Scripting?

Es fällt mir sehr schwer zu verstehen, wie man Dateideskriptoren in Shell-Skripten verwendet.

Ich kenne die Grundlagen wie

exec 5 > /tmp/foo

Also wird fd 5 zum Schreiben an foo angehängt.

exec 6 < /tmp/bar

… zum Lesen.

exec 5>&-

… schließen fd.

Was macht das jetzt?

#!/bin/bash

exec 5 > /tmp/foo 
exec 6 < /tmp/bar 

cat <&6 | while read a
do
     echo $a >&5
done

Wie ich verstehe &5 schließt das fd, also wie wird die Ausgabe nach jedem Aufruf noch erfolgreich umgeleitet?

Dies ist eine Kopie der Pasta von:Hier

Es behauptet, dies über eine einfache echo $a > file zu verwenden würde es viel schneller machen, verstehe ich aber nicht. Ich würde mich über Links zu anständigen Tutorials freuen. Ich scheine Google Powers zu versagen.

Akzeptierte Antwort:

Beachten Sie zunächst, dass die Syntax zum Schließen 5>&- ist oder 6<&- , abhängig davon, ob der Dateideskriptor zum Schreiben oder zum Lesen gelesen wird. Dieser Blogpost scheint einen Tippfehler oder Formatierungsfehler zu enthalten.

Hier ist das kommentierte Skript.

exec 5>/tmp/foo       # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar       # open /tmp/bar for reading, on fd 6
cat <&6 |             # call cat, with its standard input connected to
                      # what is currently fd 6, i.e., /tmp/bar
while read a; do      # 
  echo $a >&5         # write to fd 5, i.e., /tmp/foo
done                  # 

Hier wird nicht geschlossen. Da in diesem einfachen Beispiel alle Ein- und Ausgänge an dieselbe Stelle gehen, ist die Verwendung zusätzlicher Dateideskriptoren nicht erforderlich. Sie könnten schreiben

cat </tmp/bar |
while read a; do
  echo $a
done >/tmp/foo

Die Verwendung expliziter Dateideskriptoren ist nützlich, wenn Sie nacheinander in mehrere Dateien schreiben möchten. Stellen Sie sich beispielsweise ein Skript vor, das Daten in eine Datenausgabedatei ausgibt und Daten in einer Protokolldatei und möglicherweise auch Fehlermeldungen protokolliert. Das bedeutet drei Ausgabekanäle:einen für Daten, einen für Protokolle und einen für Fehler. Da es nur zwei Standarddeskriptoren für die Ausgabe gibt, wird ein dritter benötigt. Sie können exec aufrufen um die Ausgabedateien zu öffnen:

exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&-  # close the data output file
echo "output file closed" >&3

Die Bemerkung zur Effizienz kommt ins Spiel, wenn Sie eine Umleitung in einer Schleife haben, wie diese (vorausgesetzt, die Datei ist zunächst leer):

while …; do echo $a >>/tmp/bar; done

Bei jeder Iteration öffnet das Programm /tmp/bar , sucht bis zum Ende der Datei, hängt einige Daten an und schließt die Datei. Es ist effizienter, die Datei ein für alle Mal zu öffnen:

while …; do echo $a; done >/tmp/bar

Wenn mehrere Umleitungen zu unterschiedlichen Zeiten stattfinden, wird exec aufgerufen Umleitungen durchzuführen, anstatt einen Block in eine Umleitung zu packen, wird nützlich.

exec >/tmp/bar
while …; do echo $a; done

Unter io-redirection finden Sie mehrere weitere Beispiele für die Weiterleitung Tag auf dieser Seite.

Verwandt:Anpassen der Bash-Shell:Fett/Farbe des Befehls?
Linux
  1. Was bedeutet Exec 3?

  2. Sollte ich Apt oder Apt-get In Shell Scripting verwenden?

  3. So vergleichen Sie Zeichenfolgen in Bash Shell-Skripten

  4. Verhindern Sie die Vererbung von Dateideskriptoren während des Linux-Forks

  5. Threads und Dateideskriptoren

Bash-Skripting – Bedingte Anweisungen

Bash-Scripting(III)

Was ist Shebang in Linux Shell Scripting?

Shell-Scripting Teil 4 – Eingabe, Ausgabe und Umleitung

Shell-Scripting Schritt-für-Schritt-Tutorial

Was ist eine .sh-Datei?