cpコマンドはターゲットのシンボリックリンクをたどり、リンクを上書きするのではなくリンク先を削除します。

cpコマンドはターゲットのシンボリックリンクをたどり、リンクを上書きするのではなくリンク先を削除します。

sd/common.py -> actual_file生成されたファイルに置き換えるシンボリックリンクがあります。

しかし、そのたびに

cp /tmp/Star_Wrangler/common.py sd/common.py

...私が望むようにシンボリックリンクを置き換えるのではなく、コピーして/tmp/Star_Wrangler/common.py上書きします。actual_fileコピーする前にシンボリックリンクを削除することを忘れるたびに、これが発生します。

私が期待する動作を得るためのオプションはありますか?マニュアルを見ましたが、すべてのターゲットへのシンボリックリンクではなく、ソースへのシンボリックリンクについて話します。

答え1

どのUnixを使用しているかによって異なります。

cp -f一部のBSDシステム(OpenBSD、FreeBSD)では、シンボリックリンクのリンクを解放(削除)してソースコードに置き換えることがわかります。

GNUではcp同じ効果がないため、longオプションを使用する必要があります--remove-destination

macOSでは、cp -cマニュアルの説明に従って「ファイルのコピー」を使用してくださいclonefile(2)

NetBSDではcp -a(「アーカイブモード」、このシステムと同じcp -RpP)を使用してください。すべてのシステムに同じまたは類似の-aオプションがありますが、GNU、macOS、OpenBSD、またはFreeBSDでは機能しませんcp(GNUシステムでは同じ-dR --preserve)。

あなたはこれに直接言及しました:ファイルをコピーする前にリンクを削除すると問題が解決します。このrmユーティリティは、リンクが参照するファイルではなくリンクを削除します。これは、シンボリックリンクを通常のファイルに置き換える最も移植可能な方法でもあります。

スクリプトを書くrmときcp

インタラクティブな作業中にこの作業を忘れ続けると、cpこの状況に特定のオプションを使用することも忘れられます。

答え2

シンボリックリンクの動作は、シンボリックリンクだけでなく、組み込みcp関数(または対応するエイリアス)chmodに対しても非常に混乱します。chowntest[ .. ]

まず、シンボリックリンクを削除します。rm -f sd/common.py)、次にcp

もちろん、システムごとにバージョンごとにcpこれを行うオプションは異なりますが、気をつけやすいです。

あなたができるもう一つのことは、cpシンボリックリンクの結果を避け、目標にすることです。ln -sf SOURCE DESTINATION(両方のパラメータは絶対パスです。)混乱を招くことなく、すべてのPOSIXシステムで動作します。-f既存のDESTINATIONファイル/シンボリックリンクを削除します(ああ、ディレクトリを除く)。realpathこれを相対/絶対パス問題の防止と組み合わせることができます。

ln -sf "$(realpath "$SOURCE")" "$(realpath "$DESTINATION")"

関連情報