次の設定を検討してください。
~/Desktop/Public/subdir
~/Desktop/subdir --> ~/Desktop/Public/subdir (symbolic link)
今私はこれをします:
cd ~/Desktop/subdir
これにより、リンクされたディレクトリにリンクされます。
今コマンドを実行すると:
cd ..
私は再びDesktop
ディレクトリに移動します。これは、cdコマンドがコンテキスト・コマンドであることを意味します。つまり、subdir
シンボリックリンクを介して入力したことを覚えています。
ただし、コマンドを実行すると
cp testfile ..
testfile
にコピーされますDesktop/Public
。
私cd
は(通常は予測できない)動作を好みますcp
。とにかく、これらの行動の違いの理由が何であるかを知りたいです。ただレガシー問題なのか、それとも合理的な理由がありますか?
答え1
cd
aを介してディレクトリに入ったことを知っているのは、ディレクトリがsymlink
シェルに組み込まれているためです。このcp
コマンドは外部バイナリであり、コマンドライン引数と環境変数を介してのみデータを渡します。環境変数に次のデータが含まれていません。どのように現在のディレクトリを入力しました。
を使用すると、一貫性を維持したいのと同じ機能を実現bash
できます。これを達成します。マンページから:cd
cp
set -P
-P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the
logical chain of directories when performing commands which change the current directory.
答え2
cd
説明されているように作業する場合にのみ、cd
シェルのトリックにすることができます。..
親ディレクトリのエントリです。あなたの場合の親はsubdir
することもPublic
できませんDesktop
。したがってcp
、正しく考えると、リダイレクト(たとえば>
)でも同じ動作が得られます。
CDの例では、「ユーザーフレンドリーな」トリックを使用して実際のように動作します。バラよりhttps://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links
その機能が本当に必要な場合は、次のものを使用する必要があります。
cp testfile "${PWD##*/}"
(シェルトレースに従って現在のディレクトリの親ディレクトリにコピーされます)zshでは、これを次のように単純化できます。cp testfile $PWD:h
答え3
彼とは正反対です。他のアプリケーションと同様に動作し、現在のディレクトリの親ディレクトリとしてcp
解釈されます。..
これは、カーネルがこれを..
現在のディレクトリの親ディレクトリとして解釈するためです。
シンボリックリンクを実行するときにcd
渡すパスは、cd
ターゲットディレクトリの親ディレクトリを明確に表していません。を実行すると、ターゲットはcd ~/Desktop/subdir
シンボリック/home/konstantin/Desktop/subdir
リンクではありません。宛先ディレクトリはです/home/konstantin/Desktop/Public/subdir
。 (または賢明に言えば、ターゲットディレクトリはルートディレクトリsubdir
のサブディレクトリであるPublic
サブディレクトリです。)いいえ:サブディレクトリが存在しない場合にのみ親ディレクトリのプロパティです。 。home
/home/konstantin/Desktop/subdir/..
/home/konstantin/Desktop
/…stuff…/subdir
/…stuff…
ディレクトリへのシンボリックリンクをディレクトリとして扱うのが便利な場合が多いため、シェルはシンボリックリンクトレースを実行します。を実行すると、cd
シェルは宛先に到達するために使用したパスを記憶します(おそらくシンボリックリンクを使用して)。..
引数cd
(または同様のシェル組み込み関数(例))でこれを使用すると、シェルpushd
はテキストを現在のディレクトリに解釈するのではなくテキスト解釈を実行します..
。これにより、シンボリックリンクが実際にディレクトリであるかのように動作します。cd /some/stuff/../more
cd /some/more
cd
テキスト解析を..
論理ディレクトリ追跡といい、ファイルシステム解析を..
物理ディレクトリ追跡と呼びます。物理ディレクトリトレースを有効にするには(テキストの解釈がオフになるなど..
)、この-P
オプションをに渡しますcd
。この-L
オプションを無効にすると、論理トレースが強制的に有効になります。論理トレースはデフォルトでオフになっています。set -P
bashまたはzshを使用してオフにsetopt chase_links
することができます。
このコマンドは、pwd
シェルが追跡する現在のディレクトリを表示します。同様に、またはオプションを使用して論理または物理トレースを強制cd
できます。-L
-P
これはすべてシェル内で発生します。このような外部アプリケーションは、cp
トレースシェルの内部で何が起こっているのかわかりません。したがって、コマンドのパラメータで論理ディレクトリトレースを使用する前に、論理トレースに依存しないパスに変換する必要があります。
シェル変数はPWD
現在のディレクトリを追跡します($PWD
印刷された文字列と同じ文字列を含むpwd
)。/..
論理トレースにのみ適用されるエントリを追加する代わりに、現在のディレクトリへのトレースパスの最後のテキストコンポーネントを削除したい場合は、テキストメソッドを使用できます。
cp testfile "${PWD##*/}"
またはzshから:
cp testfile $PWD:h
入力したい..
ディレクトリと異なる表現を考える必要がない場合は、目的の宛先ディレクトリとしてcd
実行し、コマンド引数に宛先パスを使用します。
cp testfile "$(cd .. && pwd)"