web-dev-qa-db-ja.com

ディレクトリを指すシンボリックリンクを作成するには、どのべき等コマンドを使用できますか?

コマンドをシェルスクリプトに入れて、ディレクトリへのシンボリックリンクを作成しますが、このスクリプトは何度も実行される可能性があるため、その後の呼び出しでは、コマンドは何も変更しません。

ディレクトリ構造は次のとおりです。

% tree /tmp/test_symlink 
/tmp/test_symlink
├── foo
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

foo/というディレクトリを指すスニペットと呼ばれる/tmp/test_symlink/repo/resources/snippetsにシンボリックリンクを作成します。
だから私は走る:

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'

これにより、望ましい結果が得られます。

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
├── foo
│   └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

5つのディレクトリ、5つのファイル

ただし、コマンドを再度実行すると、

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets/snippets' -> '/tmp/test_symlink/repo/resources/snippets'

それはディレクトリへのシンボリックリンクを作成します、そこにシンボリックリンクがすでに存在している場合、実際のディレクトリ内にシンボリックリンクを置きます

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
├── foo
│   └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets -> /tmp/test_symlink/repo/resources/snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

なぜこれが起こっているのですか?コマンドを変更して、その後の呼び出しでこの奇妙な効果が発生しないようにするにはどうすればよいですか?

16
the_velour_fog

これには-Tオプションを使用する必要があります。これはlnに、リンク名を常にディレクトリとしてではなく、目的のリンク名として扱うように指示します。

このオプションを使用しない場合、lnにディレクトリとして存在するリンク名を指定すると、そのディレクトリ内のターゲットへの新しいリンクが作成されます。

-TはGNU-ism(少なくとも、POSIXにはありません)ですが、すでに-vも使用しているので、GNU-ismでもあるので、問題はないと思います。

または、親ディレクトリをリンク名として指定するだけで、リンクが常に(再)作成されます。

ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/

これは、シンボリックリンクがターゲットと同じ名前であるため機能します。

16
Stephen Kitt