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

Piping für Schleifenausgang verhindert lokale Variablenänderung?

Ich versuche, eine einfache Bash-Funktion zu schreiben, die als Argumente eine Reihe von Dateien und/oder Verzeichnissen akzeptiert. Es sollte:

  1. Dateinamen vollständig qualifizieren.
  2. Sortieren Sie sie.
  3. Duplikate entfernen.
  4. Drucken Sie alles, was tatsächlich vorhanden ist.
  5. Gib die Anzahl nicht vorhandener Dateien zurück.

Ich habe ein Skript, das fast das tut, was ich will, aber bei der Sortierung herunterfällt. Der Rückgabewert des Skripts in seiner jetzigen Form ist korrekt, die Ausgabe jedoch nicht (unsortiert und Duplikate). Wenn ich den | sort -u wie angegeben, ist die Ausgabe korrekt, aber der Rückgabewert ist immer .

Hinweis:Einfachere Lösungen zur Lösung des Problems sind willkommen, aber die Frage ist wirklich, warum dies in dem Code auftritt, den ich habe. Das ist der Grund, warum das Hinzufügen der Pipe anscheinend das Skript daran hindert, die Variable r zu inkrementieren ?

Hier ist das Skript:

function uniqfile
{
    local r=0 

    for arg in "[email protected]"
    do  
        readlink -e "$arg" || (( ++r ))

    done #| sort -u    ## remove that comment

    return $r
}

Akzeptierte Antwort:

Dies ist aufgrund dieser Funktion eine bekannte Bash-Falle :

Jeder Befehl in einer Pipeline wird als separater Prozess (d. h. in einer Subshell) ausgeführt.

so dass geänderte Variablen lokal in der Subshell sind und nicht sichtbar sind, sobald sie wieder in der übergeordneten Shell sind.

Um dies zu vermeiden, formulieren Sie Ihren Code um, um die Pipeline zu vermeiden, mit einer Prozessersetzung:

 for arg in "[email protected]"
    do  
        readlink -e "$arg" || (( ++r ))

    done > >(sort -u)

Linux
  1. Beispiele für Bash-For- und While-Schleifen

  2. Bash für Schleifenbeispiele

  3. Wie sortiere ich eine Datei basierend auf ihren numerischen Werten für ein Feld?

  4. Rohrleitungsausgang zum Schneiden

  5. Unterschiedliche Farbe für Befehl und Ausgabe

Bash für Schleife

Die for-Schleife in Shell-Skripten verstehen

Die Bash FOR-Schleife erklärt und vereinfacht

Rückgabecode von sed für keine Übereinstimmung

Verschachtelte for-Schleife

Wie kann ich die Ausgabe von du -h nach Größe sortieren?