私はシンボリックリンクについて完全に誤解したか(おそらく)ある時点で動作が変わり、今追いついています。
/tmp/scripts
説明を簡単にするために、ファイルシステムにスクリプトディレクトリがあります。このスクリプトディレクトリは、プロジェクト内にシンボリックリンクを作成して任意のプロジェクトに追加するためのものです。つまり、ln -s /tmp/scripts $(PROJECT)/scripts
このディレクトリのスクリプトは../config
(つまり、プロジェクトのサブディレクトリ)でいくつかのプロジェクト関連情報を見つけることを期待しています。しかし、私が見つけたのはスクリプトディレクトリでスクリプトが実行されている場合代わりに、相対パスを確認して/tmp/config
(存在しない)表示します。$(PROJECT)/config
本物シンボリックリンクコンテキストを無視したスクリプトディレクトリの場所。これはcd $(PROJECT)/scripts; pwd
、シンボリックリンクコンテキストが表示された場合でも同様です。
以下は、Ubuntu 16.04でBash 4.3.48を使用する簡単な例です。
$ mkdir a
$ touch a/apples
$ mkdir -p b/a
$ touch b/a/bananas
$ mkdir -p b/c
$ ln -s b/c c
$ cd c
$ pwd
/home/user/c # note this does not show '/home/user/b/c'
$ ls ../a
bananas
$ cd ../a
$ ls
apples
これは、シンボリックリンクの背後にある作業ディレクトリを持つプロセスがそれを呼び出すプロセスと同じ環境を持っていないことを示唆しているので、私を驚かせます。
たぶんいつもこんな感じでしたか?スクリプトプロセスが実際にまだ$(PROJECT)/scripts
入力されていないことを知っているのはなぜですかpwd
?偽物ですかpwd
?誰かがこれを説明できますか?
編集:以下は、まず相対ディレクトリを設定してからスクリプト(この場合は単純なMakefile)を作成して呼び出す簡単な実際の例です。
#!/bin/bash
mkdir -p a
echo "A:=42" > a/Config
mkdir -p b/a
echo "A:=77" > b/a/Config
mkdir -p b/c
ln -sfn b/c c
echo -e "include ../a/Config\nall:\n\t@echo \${A}" > c/Makefile
cd c
make
これは出力され77
、私はそれが42
シンボリックリンクされたMakefileなどで使用するためにプロジェクトで設定された値になるので、出力できるようにしたいと思います。実際、ディレクトリはb/a
実際には存在しないので、次のようになります。
#!/bin/bash
mkdir -p a
echo "A:=42" > a/Config
mkdir -p b/c
ln -sfn b/c c
echo -e "include ../a/Config\nall:\n\t@echo \${A}" > c/Makefile
cd c
make
次に続く:
$ ./setup
Makefile:1: ../a/Config: No such file or directory
make: *** No rule to make target '../a/Config'. Stop.
ベストアンサー1
cd
期待どおりに動作するようにするには、次に電話してください。
cd -P c
以下を印刷しますpwd
。
/home/user/b/c
現在見ている問題は、シェルが不満足なPOSIX決定に従い、デフォルト値を採用したためにcd -L
発生します。これにより、$PWD
/home/user/c
シェルコマンドはをcd ..
呼び出さずにchdir("..")
値$PWD
を1つの要素だけchdir()
短縮し、短縮されたパスに移動してcd ..
元の位置に戻り、シェルが明白であることを覚えています。
たとえば、人々が走る傾向があるため、これはセキュリティリスクです。
ls ../
結果に満足したら、以下を実行できます。
cd ../; rm *.c
予想とは異なるファイルを削除します。
POSIXのデフォルトはデフォルトの動作をモデル化ksh88
し、kshがそのデフォルトの動作を導入したとき、AT&Tはcd -P
Bourne Shellのデフォルト動作としてより安全なバリエーションを実装することにしました。