存在するUbuntuのポストに聞いてください、設定されていない場合は、globstarを使用してファイルを見つけますPATH
。
$ shopt -s globstar; for v in /**/vim; do [[ -x $v && -f $v ]] && echo "$v"; done
/etc/alternatives/vim
/usr/bin/vim
/usr/bin/X11/vim
今考えてみると、この出力はちょっと変なようです。/usr/bin/X11
シンボリックリンクです/usr/bin
。
$ readlink /usr/bin/X11
.
したがって、sの無限再帰がありますが、X11
出力には最初の再帰のみが表示されます。奇妙なことは、aが/usr/**
まったく落ちないということです。X11
$ printf "%s\n" /usr/bin/** | grep X11
/usr/bin/X11
最初の出力と最後の出力をどのように調整しますか?
コメントから:
Ubuntu 16.04でBashバージョン4.4.18(1)を使用しています。
ベストアンサー1
tl;dr - Bash 拡張は無限シンボリックリンクループ (in bash >= 4.3
) を防ぐために複雑であり、あなたと私は両方ともあなたが投稿したコマンドで何をしているのかを誤解しました。
bash >= 4.3
私はあなたがの説明を再現することができないのでbash 4.2.46
(予想どおり)再帰限界に達するまで繰り返すと仮定します。
これをしばらく見守り、状況をシミュレートするためにテストディレクトリを設定します。コアは、各例でbash拡張がどのように行われるかです。拡張子が後ろにあるかどうかに応じて動作が異なります/
。そして私たち霊長類の場合、このような例を見ると、この時点で認知的不調和があります。
~からbash shoptのドキュメント:
globstar
設定されると、ファイル名拡張コンテキストで使用されるパターン "**" は、すべてのファイルとゼロ個以上のディレクトリとサブディレクトリと一致します。パターンの後に「/」が続くと、ディレクトリとサブディレクトリのみが一致します。
ここに説明するためのテスト設定があります。
$ mkdir -p test/nested
$ cd test
$ touch sneaky
$ touch nested/sneaky
$ cd nested
$ ln -s . looper
$ cd ..
次のディレクトリ構造を作成します。
test/
- sneaky
- nested/
- sneaky
- looper -> ./
これは私のテストディレクトリで見つけたものを複製します。
$ for apath in ../**/sneaky; do echo "$apath"; done
../test/nested/looper/sneaky
../test/nested/sneaky
../test/sneaky
$ printf "%s\n" ../** | grep sneaky
../test/nested/sneaky
../test/sneaky
最初の例では、globはに拡張されています。 globの後ろにaがあるので、(test/nested/looper, test/nested, test)
リンクに従わずに停止します。looper
/
次に、ここに追加して/sneaky
コレクションを取得します(test/nested/looper/sneaky, test/nested/sneaky, test/sneaky)
。
2番目の例では、globは次に展開されます(test/nested/looper, test/nested/sneaky, test/nested, test/sneaky, test)
(削除してそれを確認できます| grep sneaky
)。
繰り返しますが、この拡張はリンクに従わず、looper
この場合は追加しないため、結果から削除されます/sneaky
。../test/nested/looper/sneaky
一方、我々は../test/nested/sneaky
glob../test/sneaky
の後に/