ls .*がls ./.*と異なるファイルを表示するのはなぜですか?

ls .*がls ./.*と異なるファイルを表示するのはなぜですか?

現在、ディレクトリに空のファイル.ignoramusがあります。

bojan@localhost:~$ echo $GLOBIGNORE
.ignoramus
bojan@localhost:~$ ls .* | grep ignor
bojan@localhost:~$ ls ./.* | grep ignor
./.ignoramus

使用済みツール ls(GNU coreutils) 8.23 GNU bash, バージョン 4.3.42(1)-リリース(x86_64-pc-linux-gnu)

答え1

この設定は、コマンドラインでワイルドカード文字を展開すると$GLOBIGNOREシェルによって処理されます。最初のケースでは、シェルは最初.*に展開されます.ignoramus。これは一致するため、$GLOBIGNOREに渡された名前には含まれませんls

2番目のケースでは、シェルは次のよう./.*に展開されます。./.ignoramusいいえ$GLOBIGNOREに設定すると、$GLOBIGNORE2.ignoramus:./.ignoramus番目のコマンドの動作が最初のコマンドと一致します。

答え2

簡単な理由:文字列の./.ignoramus不一致.ignoramus

簡単な解決策:使用GLOBIGNORE=*ignoramus(最後の詳細を参照)。

$ GLOBIGNORE=*ignoramus
$ ls .* | grep ignor                 ### empty
$ ls ./.* | grep ignor               ### also empty

/アスタリスクは何でも一致します(名前の前のスラッシュも含む)。
もちろんこれも一致しますfoobar.ignoramus。いくつかの回避策については、最後を参照してください。


詳細な答え:

これは通常のファイルでも発生します。

$ mkdir /tmp/mytest; cd /tmp/mytest
$ touch f1 f2 filetotest
$ GLOBIGNORE=filetotest
$ ls -1
f1
f2
filetotest

$ ls -1 f*
f1
f2

$ ls -1 *
f1
f2

$ ls -1 ./f*
./f1
./f2
./filetotest

GLOBIGNOREは一致しませんが、./filetotest以下を使用する場合:

$ GLOBIGNORE="*filetotest"
$ ls -1 ./f*
./f1
./f2

$ ls -1 ./*
./f1
./f2

$ ls -1
f1
f2
filetotest

GLOBIGNOREのパターンは(something)filetotest

あなたの例:

$ touch .ignoramus
$ GLOBIGNORE='*ignoramus'
ls -1a
.
..
f1
f2
filetotest
.ignoramus

$ ls .* | grep ignor
$ ls ./.* | grep ignor

ファイルの前にいくつかのパスがある場合でも機能します。

$ GLOBIGNORE='*ignoramus:*filetotest'
$ mkdir -p long/dir/to/test
$ touch long/dir/to/test/{f3,f4,.ignoramus,.other,filetotest}

$ ls -1 long/dir/to/test/f*
long/dir/to/test/f3
long/dir/to/test/f4

$ ls -1 long/dir/to/test/.[^.]*
long/dir/to/test/.other

$ shopt -s dotglob
$ ls -1 long/dir/to/test/*
long/dir/to/test/f3
long/dir/to/test/f4
long/dir/to/test/.other

$ unset GLOBIGNORE; shopt -s dotglob
$ ls -1 long/dir/to/test/*
long/dir/to/test/f3
long/dir/to/test/f4
long/dir/to/test/filetotest
long/dir/to/test/.ignoramus
long/dir/to/test/.other

もちろんこれも一致しますbar.ignoramus。必要でない場合は、次を使用します。

$ GLOBIGNORE=.ignoramus:./.ignoramus

または任意のパスを含めたい場合:

$ GLOBIGNORE=.ignoramus:*/.ignoramus

関連情報