Nach dem Ausführen eines Skripts zum Auflisten des Unterordners wird ein Stern für ein leeres Verzeichnis gedruckt

7

Ich habe versucht, ein Shell-Skript zu schreiben, das einen Verzeichnispfad d als Argument verwendet und rekursiv eine tief eingerückte Liste aller Dateien und Verzeichnisse in d druckt. Das Argument d ist jedoch optional. Wenn kein Argument angegeben wird, wird eine tief eingerückte Liste aller Dateien und Verzeichnisse im aktuellen Verzeichnis gedruckt. Hier ist mein Code:

# the method for tree

myspace=""
spaceCount=0
tree(){     
  cd "$1"
  for i in *; do
    if [ -d "$i" ]; then
      echo -n "|"   
      for (( j=0;j<spaceCount;j++ )) 
      do 
        echo -n "$myspace"  
      done
      echo "--$i"
      spaceCount=$((spaceCount+1)) 
      myspace="  |"
      tree "$i"
    else
      echo -n "|"
      for (( j=0;j<spaceCount;j++ )) 
      do 
        echo -n "$myspace"  
      done
      echo "--$i"
    fi
  done
  cd ../
  spaceCount=$((spaceCount-1))
}


if [ "$1" != "" ]; then
  file="$1"
fi
echo ".$file"
tree "$file"

Wenn ein Ordner leer ist, wird ein Stern wie folgt gedruckt:Geben Sie hier die Bildbeschreibung ein

Wie kann ich das Problem lösen?

Sphoenix
quelle

Antworten:

11

In bashund Bourne-ähnlichen Shells im Allgemeinen ( zshmit Ausnahme) stimmen solche Globs *nicht mit einer Dateierweiterung überein (Ihr Skript verwendet eine ksh93Syntax, die auch von bashund erkannt wird zsh, obwohl in zshnicht übereinstimmenden Globs standardmäßig schwerwiegende Fehler auftreten). .

echo *in einem Verzeichnis, das keine Dateiausgaben (oder nur versteckte Dateien) enthält *.

for i in *Verwenden Sie hier stattdessen for i in *(N)( zsh) oder for i in ~(N)*( ksh93) oder setzen Sie bei Verwendung bashdie Option nullglob (with shopt -s nullglob) so, dass die nicht übereinstimmenden Globs nichts tun.

Alternativ können Sie [ -e "$i" ] || continueam Anfang oder in Ihrer forSchleife ein hinzufügen, um das herauszufiltern, *indem Sie prüfen, ob eine Datei vorhanden ist (dies würde sich auf das Verhalten von Verzeichnissen auswirken, die Sie gelesen haben, die jedoch keine Suchberechtigungen haben¹).

Weitere Informationen finden Sie unter Warum ist nullglob nicht die Standardeinstellung?


¹ Wird in diesen Verzeichnissen *auf alle nicht ausgeblendeten Dateien erweitert, gibt jedoch [ -e "$i" ]für alle Dateien false zurück, da der stat()Systemaufruf mit verweigerter Berechtigung zurückgegeben wird

Stéphane Chazelas
quelle
Wo soll ich hinzufügen shopt -s nullglob?
Sphoenix
@sphoenix, vor jedem Befehl, der einen Glob verwendet, dessen Erweiterung Sie die Nullglob-Regel verwenden möchten.
Stéphane Chazelas
Alternativ können Sie [ -e "$i" ] || continueam Anfang oder in Ihrer forSchleife ein hinzufügen, um das herauszufiltern, *indem Sie prüfen, ob eine Datei vorhanden ist (dies würde sich auf das Verhalten von Verzeichnissen auswirken, die Sie gelesen haben, für die Sie jedoch keine Suchberechtigungen haben). Könnten Sie bitte näher erläutern, ob "das Verhalten von Verzeichnissen, die Sie gelesen haben, aber keine Suchberechtigungen haben", beeinflusst wird?
Sphoenix
@sphoenix, siehe bearbeiten.
Stéphane Chazelas