Pek çok kırık sembolik bağı nasıl “yeniden bağlayabilirim”?


54

Ben altında dosyalara sembolik bağlantıları bir demet sahip bir dizin ağacı var /home... Ancak, ben taşımış /homeetmek /mnt/homeve kısa yollarda tüm "yeniden bağlamak" için bir yol gerekir. Bu işlevsellik var mı, yoksa bunu yapmak için bir komut dosyası yazmam gerekiyor mu?

Örnek olarak, aşağıdakine benzer bir şey var:

[root@trees ~]# ls -l /mnt/home/someone/something
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/e

/mnt/home/someone/something/subdir:
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/subdir/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/subdir/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/subdir/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/subdir/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/subdir/e

Tüm sembolik bağları bulabilecek ve aynı yerlere yeniden bağlanacak, ancak /mnt/homebunun yerine alt tarafa bir komut istiyorum/home

Böyle bir komut var mı?

Yanıtlar:


55

Sembolik bir bağlantıyı yeniden hedefleme komutu yoktur, yapabileceğiniz tek şey onu kaldırmak ve başka bir tane oluşturmaktır. Eğer GNU yardımcı programları var varsayarsak (örneğin olmayan gömülü Linux veya Cygwin), kullanabilirsiniz -lnameait birincil findonların hedefi tarafından sembolik bağlantıları maç için ve readlinkbağlantının içeriğini okumak için. Test edilmemiş:

find /mnt/home/someone/something -lname '/home/someone/*' \
     -exec sh -c 'ln -snf "/mnt$(readlink "$0")" "$0"' {} \;

Bu sembolik bağları göreceli yapmak daha iyi olur. Pek symlinksçok Linux dağıtımında mevcut olan (aslında şu anda J. Brandt Buckley tarafından bakımı yapılan Mark Lords tarafından) adlı küçük bir yardımcı program var . Taşıma işleminden önce veya yukarıdaki gibi geçerli bağlantıları geri yükledikten sonra, symlinks -c /mnt/home/someone/somethingbir dosya sistemi sınırını geçmedikçe, belirtilen dizin altındaki tüm mutlak sembolik bağlantıları göreli sembolik bağlantılara dönüştürmek için çalıştırın .


Alınma, bu harika bir tek gömlek, ama Bash'in karakter dizisi muhtemelen yol değişikliği ile biraz sihir yapabilirdi ve daha kolay olurdu.
0xC0000022L 20

@STATUS_ACCESS_DENIED Nasıl yani? Tek dizge işlemi /mntbir yola hazırlanmaktır; birleştirme işleminden daha fazla dize işlemi yapmanız gerekmez.
Gilles 'SO- kötü olmayı'

@Gilles: üzgünüm, göreceli yollarla ilgili görüşünüzü daha çok düşünüyordum. Örneğinizin tam bir "çevirisi" için elbette haklısınız.
0xC0000022L

13

Yazarın istediği şeyin tam olarak bu olmadığını biliyorum, ancak zaten cevapları varmış gibi görünüyor, bu yüzden bunu benim gibi başkalarına soruna karıştıranlar için ekliyorum.

Aşağıdakiler, sembolik bağın hedeflerinin bir kısmının yerini alarak sabitlenebilecek bir demet kırık sembolik bağa sahip olmak gibi daha esnek bir çözüme ihtiyaç duyulması halinde yardımcı olacaktır.

Örneğin. Bir kullanıcı adının değiştirilmesinden sonra, eski kullanıcı adının yerine birçok bağlantı hedefindeki yeni kullanıcı adı ile değiştirmek için taşıma işlemi yapıldı. Aşağıda gösterilen change-simlinks adlı bir komut dosyası oluşturun:

#!/bin/bash
link=$1
# grab the target of the old link
target=$(readlink -- "$1")

# replace the first occurrence of oldusername with newusername in the target string
target=${target/oldusername/newusername}

# Test the link creation
echo ln -s -- "$target" "$link"

# If the above echo shows the correct commands are being issued, then uncomment the following lines and run the command again
#rm $link
#ln -s "$target" "$link"

ve aşağıdaki komutla arayın:

find /home/newusername/ -lname '/home/oldusername/*' -exec ~/bin/replace-simlinks {} \;

Umarım bu birine yardım

düzenleme: Bu betikteki kickstart için teşekkürler Gilles ve bağlantıları göreceli yapmak için symlinks komut dosyasını kullanma hakkında ipucu.


1
Bu çözümü daha iyi buluyorum, çünkü dizenin yerini değiştiren bir dizgenin adını değiştirmek zorunda kaldığınız durumlarda yardımcı olan bir dize kullanıyor. Çözüm, gerekirse daha karmaşık dönüşümler gerçekleştirmek için değişiklik yapmak da oldukça kolaydır.
Gallaecio

Argümanları dizenin yerine koymasını tavsiye ederim, bunun için eğik çizgi kullanmak için yapılması gerekiyor, örneğin OP'nin sorusundaki yol için. target=${target/"/home"/"/mnt/home"}Yine de çok faydalı. Teşekkürler.
Walter Nissen

3

/homeSembolik link olarak oluşturun /mnt/home, mevcut tüm sembolik linkler tekrar geçerli olacaktır.


2
Bağlama-bağlama çoğu zaman programların sembolik bağların farkında olduğu ve gerçeğe bağlı olarak farklı davrandığı senaryolardaki sembolik bağlardan daha az kırılgan olma eğilimindedir ...
0xC0000022L 20
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.