好奇心で次のコマンドを実行しました。
mkdir haha
cd haha
ln -s ../haha haha
これにより、次のような再帰構造が生成されます。
┌────────┐
V │
haha/ │
haha/────┘
私はどのくらいの距離に行くことができるかを知りたかったので、入力して押したcd haha/
ままTabbashに複数のhaha/
sを自動補完させました。最も多くの部分cd haha/haha/<SNIP>/haha/
(合計40 "ハハ/")を自動補完し、突然完了を停止します(異常動作#1)。私はを押したEnter。それを実行した後、pwd
私は実際にそのディレクトリ/home/me/haha/<SNIP>/haha/haha
(41 "haha /"s)にあることがわかりました。私はこのディレクトリで別のディレクトリを実行cd haha
しました/home/me/haha
。pwd
ああ?なぜこれが起こるのですか? bashの特徴ですか?ファイルシステムの制限(btrfsを使用しています)?他にはありませんか?
答え1
これを行うcd haha/haha/...
場合、または実際にパスシンボリックリンクを使用している場合は、カーネルはパスが指す場所を見つけるためにリンクを解析する必要があります。 Linuxでは、ELOOP(Excessive Levels of Symbolic Links)を使用して回復する前に確認できるリンク数に制限があります。
これpath_solution(7) のマニュアルページ40のリンク制限について言及:
スタックオーバーフローからカーネルを保護し、サービス拒否を防ぐために、最大再帰深度と追従する最大シンボリックリンク数に制限があります。最大値を超えると、ELOOPエラー(「シンボリックリンクレベルが多すぎます」)が返されます。
[...] Linux 4.2では、再帰使用を排除するためにカーネルのパス名解析コードが再設計されているため、残りの制限はフルパス名の最大解像度40です。
タブの完成を繰り返すと、ある時点でオペレーティングシステムが再生を拒否してエラーをスローするまで、シェルがディレクトリリストなどを要求することがhaha/
ありhaha/haha/
ます。タブ完了ルーチンがユーザーにエラーを公開していないようです。おそらくあまりにも騒々しくないでしょう。cd haha/...
長すぎるパスを使用しようとすると、エラーメッセージが表示されます。ただし、制限のすぐ下のパスでは機能します。
デフォルトでは、シェルはpwd
リンクにパスを表示するためにディレクトリにアクセスするために使用したパスを覚えようとします。これにより、リンクかどうかに関係なく開始したcd foo; cd ..
場所に戻ることができます。foo
制限に達すると、アクションを実行すると、cd haha
Bash が最初にchdir(".../haha/haha")
使用されます。みんなPath、現在のリンクが多すぎて呼び出しが失敗します。その後、シェルは派手に努力するのではなく、chdir("haha")
現在の場所の解析を呼び出して使用してgetcwd()
リンクのないパスを取得します。