cp SOMEFILE ..シンボリックリンクを介して別のディレクトリにコピーcd

cp SOMEFILE ..シンボリックリンクを介して別のディレクトリにコピーcd

次の設定を検討してください。

~/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

cdaを介してディレクトリに入ったことを知っているのは、ディレクトリがsymlinkシェルに組み込まれているためです。このcpコマンドは外部バイナリであり、コマンドライン引数と環境変数を介してのみデータを渡します。環境変数に次のデータが含まれていません。どのように現在のディレクトリを入力しました。

を使用すると、一貫性を維持したいのと同じ機能を実現bashできます。これを達成します。マンページから:cdcpset -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/../morecd /some/morecd

テキスト解析を..論理ディレクトリ追跡といい、ファイルシステム解析を..物理ディレクトリ追跡と呼びます。物理ディレクトリトレースを有効にするには(テキストの解釈がオフになるなど..)、この-Pオプションをに渡しますcd。この-Lオプションを無効にすると、論理トレースが強制的に有効になります。論理トレースはデフォルトでオフになっています。set -Pbashまたは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)"

関連情報