
私はディレクトリパスdを引数として使用し、d内のすべてのファイルとディレクトリの深くインデントされたリストを繰り返し印刷するシェルスクリプトを作成しようとしています。ただし、d引数はオプションであり、引数が指定されていない場合は、現在のディレクトリにあるすべてのファイルとディレクトリのインデントリストが印刷されます。これは私のコードです。
# 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"
ただし、フォルダが空の場合、次のアスタリスクが印刷されます。
この問題をどのように解決できますか?
答え1
bash
通常、Bourneスタイルのシェル(zsh
例外を含む)では、*
一致しないファイルのglobはそれ自体で拡張されます。構文を使用するスクリプトは、基本的に一致しない glob についても認識されksh93
ます。 、致命的なエラーが発生します)。bash
zsh
zsh
echo *
ファイルが存在しないか隠されたファイルのみがあるディレクトリでは*
。
for i in *
ここでは、 for i in *(N)
(zsh
)またはfor i in ~(N)*
(ksh93
)を代わりに使用するか、使用する場合はbash
次のように設定します。空のボールshopt -s nullglob
拡張と一致しないglobに対して何もしないようにオプション()を使用します。
あるいは、ファイルが存在することを確認して、フィルタリングするループまたは先頭に[ -e "$i" ] || continue
ファイルを追加することもできます(読み込んだが検索権限を持たないディレクトリの動作に影響を与えます)。for
*
詳細については、以下をご覧ください。nullglobがデフォルトではないのはなぜですか?
¹このディレクトリでは、*
隠されていないすべてのファイルに展開されますが、システムコールが返される[ -e "$i" ]
ため、各ファイルに対してfalseを返します。stat()
許可が拒否されました