Bir dizine işaret eden bir sembolik bağ oluşturmak için hangi idempotent komutunu kullanabilirim?


16

Dizine bir symlink oluşturacak bir kabuk komut dosyasına bir komut koymak istiyorum, ancak bu komut dosyası tekrar tekrar çalıştırılabilir, bu nedenle sonraki çağrılarda, komut hiçbir şey değişmemelidir.

Dizin yapısı şöyledir:

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

foo/Dizine işaret eden snippet'lerde bir sembolik bağlantı oluşturmak istiyorum /tmp/test_symlink/repo/resources/snippets.
Bu yüzden koşuyorum:

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

istenen sonucu verir.

% 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 dizin, 5 dosya

Ancak, komut yeniden çalıştırıldığında,

% 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'

bir dizine bir sembolik bağlantı oluşturur, burada symlink'in mevcut olduğu symlink'i gerçek dizinin içine koyar

% 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

bu neden oluyor ve daha sonraki çağrıların bu garip etkiyi yaratmaması için komutu nasıl değiştirebilirim?

Yanıtlar:


16

Bunun için -Tseçeneği kullanmalısınız, lnbağlantı adına her zaman istenen bağlantı adı olarak değil, asla dizin olarak davranılmasını söyler .

Bu seçenek olmadan, lndizin olarak var olan bir bağlantı adı verirseniz , o dizinin içindeki hedefe yeni bir bağlantı oluşturur.

Bunun -Tbir GNU-izm olduğunu unutmayın (en azından POSIX'te değil), ancak zaten -vbir GNU-ism olanı kullanıyorsunuz, bu yüzden bunun bir sorun olmadığını hayal ediyorum.

Alternatif olarak, yalnızca üst dizini bağlantı adı olarak belirtebilirsiniz ve bağlantı her zaman orada (yeniden) oluşturulur:

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

Bu, sembolik bağınızın hedefle aynı ada sahip olması nedeniyle çalışır.


teşekkürler, evet gnu seçenekleri mutlaka taşınabilir değildir, ancak taşınabilirlik bir gereklilik olmadığında gerçekten yararlı olabilirler. cevabın benim için çalışıyor. Man sayfasından -n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory. -T, --no-target-directory treat LINK_NAME as a normal file alwaysSymlink'i her zaman bir dosya olarak ele almanın daha iyi olduğunu düşünüyor musunuz? Bu "özel" seçeneklerin kullanımını sınırlamanın daha iyi olacağını düşünürdüm?
the_velour_fog

Mevcut olduklarını biliyorsanız, GNU'ya özgü seçeneklerden (IMO) kaçınmak için hiçbir neden yoktur. Bir idempotent komutu istediniz, idempotent -Tnasıl yapılır ln. Tercih ederseniz aynı sonucu elde etmenin başka yolları da vardır, örneğin bağlantıyı silme ve yeniden oluşturma veya foozaten var olduğunu biliyorsanız ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/(aslında bu daha iyi bir yanıt olabilir, güncelleyeceğim).
Stephen Kitt

1
cool, yes Daha önce ifsymlink varlığını tespit etmek ve symlink varsa komutu atlamak için ifadeler kullanıyordum , ancak komut dosyaları dağınık ve zor okunuyor, mkdir -ptest kullanmamak gibi idempotent ama basit bir şey için gidiyordum , mantık yok, sadece iyi ol bir gömlekleri :)
the_velour_fog

@Stephen Kitt: -T kullanımından bahsettiniz, ancak cevabınızın kod snippet'inde bulamadım. Yanlış anlıyor muyum veya bir şey mi kaçırıyorum?
Guizmoo03

@ Guizmoo03 belki de pasajı tanıtan “Alternatif” i kaçırdınız. İlk üç paragraf açıklıyor -T, ancak cevabımın sonunda kullanılmayan başka bir çözüm var -T.
Stephen Kitt

-1

En iyi burada ne olduğunu söyleyebilirim ikinci geçişte lnkomut gibi davranır cpya da mv, eğer <destination> bir "dizin" görürse, dosyayı içine koymak olacaktır, aksi takdirde <destination> Varsa, <hedef> yapar. ("slashdot" numarasının kaçındığı şey - yani <hedef> 'in var olduğundan ve bir dizin olduğundan emin olacaktır).
Ama yanılmış olabilirim.

Her iki durumda da bu işe yarıyor gibi görünüyor

ln -sfv --no-dereference /tmp/test_symlink/repo/resources/snippets/ foo/snippets
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.