次のフォルダ構造を考えてみましょう。
.
├── test1
│ ├── nested1
│ ├── testfile11
│ └── testfile12
└── test2
├── nested1 -> /path/to/dir/test1/nested1
└── testfile21
test2/nested1
ディレクトリへのシンボリックリンクtest1/nested1
。 cwdなら..
これをやろうと決心すると予想しますtest2
。しかし、私は以下の不一致を見つけました:
$ cd test2/nested1/
$ ls ..
nested1 testfile11 testfile12
$ cd ..
$ ls
nested1 testfile21
touch
また、ls
からファイルを生成するかのように動作しますtest1
。
..
引数としてcd
シンボリックリンクの親エントリを参照しますが(すべて?)他の引数はリンクされたディレクトリの親エントリを参照するのですか?シンボリックリンクに関連するパスを参照するように強制する簡単な方法はありますか?それは「反対」ですかreadlink
?
# fictional command
ls $(linkpath ..)
編集:bashを使う
答え1
コマンドを発行し、cd
2pwd
つの動作モードがあります。
-L論理モード:シンボリックリンクが解決されない
-P物理モード:操作を実行する前にシンボリックリンクを確認してください。
ここで知っておくべき重要な点は、cd ..
システムコールを呼び出さずにシェルの変数を短縮し、次にchdir("..")
chdirをその絶対パスに短縮することです。$PWD
これは物理モードで呼び出すのと同じですchdir("..")
が、論理モードでは異なります。
ここで最大の問題は、POSIX が安全性の低い論理モードをデフォルトとして使用することを決めたことです。
cd -P
を呼び出す代わりに呼び出すと、cd
操作後のchdir()
戻り値がgetcwd()
シェル変数に格納され、次の操作を実行する$PWD
とcd ..
物理的に現在のディレクトリに移動されます。
それでは、POSIXが基本的に安全性が低いのはなぜですか?
POSIXネイティブモードでシンボリックリンクを展開し、次のことを行う場合:
ls ../*.c
cd ..
rm *.c
前のコマンドでリストされたファイルとは異なるファイルを削除できますls
。
より安全な物理モードを好む場合は、次のエイリアスを設定してください。
alias cd='cd -P'
alias pwd='pwd -P'
複数のオプションを使用し-L
、-P
最後のオプションが勝つ場合でも、別の動作を得ることができます。
歴史の背景:
Bourne Shellとksh88は同時にディレクトリトラッキングコードを得ました。
Bourne Shellはより安全な物理的動作を達成し、ksh88はデフォルトと-L
オプションで安全性の低い論理モードを得ました-P
。 ksh88はcshの動作を参照できます。
POSIXはksh88の動作を採用しましたが、これが良い決定であるかどうかについて議論はありませんでした。
$PWD
注:一部のシェルはより長い値を追跡できません。PATH_MAX
これにより、絶対パスがより長いディレクトリにchdirを入力すると、狂ってしまう可能性がありますPATH_MAX
。dash
本当に欠陥のある殻です。
答え2
読むべき重要な論文は次のとおりです。http://doc.cat-v.org/plan_9/4th_edition/papers/lexnamesRob Pikeはこの問題について話します。
また、シェル(bashなど)が実際にシステムコールをcd ..
実行するのではなく、最後のコンポーネントを切り捨ててそこから変更すると言う場合は、現在のディレクトリについてどう考えるかを追跡するように指定する必要があります。chdir("..")
今は携帯電話で申し訳ありません。後で修正します。
答え3
シンボリックリンクに従うのではなく、物理ディレクトリ構造に従う-paを試してみることもできます。