Sembolik linkleri nasıl düzenleyebilirim?


64

Temel bir bağlantı sembolik bilgim, başka bir dosyaya dizge yolu içeren özel bir dosyadır. Çekirdeğin VFS'si bunun çoğunu soyutlar, ancak sembolik bağlantıların düzenlenmesi imkansız gibi görünen bir neden var mı?

Başka bir deyişle: Bir sembolik bağlantıyı düzenleyebilir miyim? Değilse neden olmasın?


Sembolik bağlantıları değiştirmenin çeşitli yolları olduğunu anlıyorum (şu anda cevaplar bölümünde iki alternatif var) ancak değiştirmenin semboliklerle başa çıkmanın tek yolu olarak göründüğü hakkında bir açıklama yapmak ilginç olacaktır. Neden sadece işaret ettikleri yeri değiştiremiyorsun?


Anlayışınız biraz sınırlı; Buna 'dosya' denmesinin tek nedeni, bunun için daha iyi bir kelime olmamasıdır.
Shadur

5
Windows varyantı olan utanç verici acımasızlığın aksine, posix tarzı sembolik bağlantılar dosya sistemi katmanında / üzerinde çalışır. Birini düzenlemenin tek yolu, dosya sistemini doğrudan düzenlemek olacaktır - ve genellikle buna değmez.
Shadur

@Shadur .lnk dosyaları gerçekten başlamak için sembolik bağlantılar değildir (ve NTFS'nin Vista'dan beri uygun sembolik bağlantıları vardır ); Bunlar komutları yürütmek için kısayollar gibidir, ister belirli bir klasöre dönüşüyor, ister belirli argümanlarla ve belirli bir CWD ile bir program başlatıyor olsun.
JAB,

Yanıtlar:


36

Bu -fsadece sessiz bir değiştirme yaparsa, ile atomik bir değiştirme yapabilirsiniz mv -T(/loc.../link bir dizin olsa bile -T'nin çalışmasını sağlar) :

ln -s /location/to/link linkname
# ... 
ln -s /location/to/link2 newlink
mv -T newlink linkname

linkname süreç boyunca erişilebilir.


7
Bu, atomik değişimi size sağlar, ancak düzenleme yerine hala bir değişiklik yapıyor olsanız da (yeni bağlantının yeni bir inode numarası vardır).
psusi

2
@ psusi Tamamen katılıyorum, bazı senaryolardaki diğer cevaplardan teknik olarak biraz daha iyi bir seçenek.
Oli,

Bağlantıyı başka bir hedefe yönlendiriyorsanız, inode numarasını değiştirmek küçük bir değişiklik gibi görünüyor.
ams

4
Bu linknamebir dizine bir bağlantı olmadığını varsayar . Bunu önlemek için GNU’da veya FreeBSD’de ise -Tseçeneğini kullanın . Bunun , bağlantının izinlerini (önemli oldukları sistemlerde) korumadığını unutmayın . mv-hln -sf
Stéphane Chazelas

Dizinin değişiklik sembolik bağ için bir başka çözüm kullanmaktır -nseçenekleri örneğin: ln -sfn DESTINATION_DIRECTORY LINK_NAME. Daha fazla bilgi için askubuntu.com/a/186227/69004
sobi3ch

22

Düzenlemeye göre, işaret ettiği dosyayı değiştirmek isterseniz, evet, şunları yapabilirsiniz:

$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 8 2009-09-23 17:12 test -> .profile

-fParametresi ( --force) o aramaya bunu neden ln geçirilen zaman unlink()hemen önce sistem çağrısısymlink()

Aşağıdaki yığın taşması cevabından alınmıştır .


9
Bunun unlink (); symlink (); atomik olmadığı için, bağlantının bulunmadığı küçük bir süre vardır.
tekrar

@ mauro.stettler Evet, haklısınız. Ama sanırım bu senin bakış açına bağlı. Sadece son sonucu hesaba katarsanız, belki de düzenlenmiş olarak düşünebilirsiniz, başka bir şey düşünülmez.
NlightNFotis,

1
Unix Zaman Paylaşma Sistemi belgesinden alıntılanan bölüm sert bağlantılar açıklar . Bunlar OP'nin sorduğu sembolik bağlardan (sembolik linklerden) tamamen farklıdır.
Ansgar Esztermann

4
Hedefinin testbir dizin olmadığını varsaydığını unutmayın . Aksi takdirde , bu dizinde ln -s -f .profile testbir .profilesembolik bağlantı oluşturabilir . GNU'nun lnbundan -Tkaçınmak için bir seçeneği var.
Stéphane Chazelas

9

Sembolik bağların atomik olarak değiştirilmesi gerekir. Onları yazmanın yarısı kadar gidersen, işe yaramazlar. Sembolik bir bağlantının içeriği oldukça küçüktür (Linux'ta en fazla 4095 karakter: bir dosyaya giden yolun maksimum uzunluğu), bu nedenle sembolik bir bağlantının bir bölümünü çekirdek düzeyinde düzenlemek için küçük bir nokta olacaktır. Bu nedenle, çekirdek sembolik bir bağlantıyı düzenlemek için herhangi bir arabirim sunmaz, yalnızca yeni bir tane oluşturmak için bir arabirim, symlinksistem çağrısı (ayrıca unlinkherhangi bir dosyayı kaldırmak için genel arabirim ) sunar.

symlinkSistem çağrısı yalnızca yeni bir simgesel bağlantı oluşturur, bu varolan herhangi bir dosya kaldırmaz. Bu can sıkıcıdır, ancak open(yeni bir dosya oluşturabilir veya mevcut bir dosyayı kesebilir, ancak yeni oluşturulan bir dosyayla mevcut bir dosyayı değiştiremez) gibi dosyalar oluşturmak için diğer sistem çağrılarıyla tutarlıdır mkdir.

Kabukta, keşfettiğiniz gibi , sembolik bir bağı atomik olarak lnkomutla değiştiremezken ( ln -sfönceki dosyanın işaretini kaldırır, sonra sembolik bağlantıyı oluşturur), önce geçici bir ad altında sembolik bir bağlantı oluşturarak bunu yapabilirsiniz. sonra yerine yerleştirin.

tmp=$(TMPDIR=$(dirname -- "$link") mktemp)
ln -sf -- "$target" "$tmp"
mv -f "$tmp" "$link"

2
mv -f(gibi ln -sf) $linkbir dizine işaret ederse ne istersen yapmazsınız. GNU in ve mv bunun -Tiçin var. mvolacaktır (sistem çağrısını yeniden adlandırmak) her zaman düğümü değişiklik $linksüre ln -sfTaynı yeniden olabilir (+ sembolik bağlantısını kaldırmak).
Stéphane Chazelas

0

Teknik olarak, mevcut bir sembolik bağı düzenlemek için yerleşik bir komut yoktur. Birkaç kısa komutla kolayca elde edilebilir.

İşte varolan bir sembolik bağlantıyı güncellemek için yazdığım küçük bir bash / zsh işlevi :

# -----------------------------------------
# Edit an existing symbolic link
#
# @1 = Name of symbolic link to edit
# @2 = Full destination path to update existing symlink with 
# -----------------------------------------
function edit-symlink () {
    if [ -z "$1" ]; then
        echo "Name of symbolic link you would like to edit:"
        read LINK
    else
        LINK="$1"
    fi
    LINKTMP="$LINK-tmp"
    if [ -z "$2" ]; then
        echo "Full destination path to update existing symlink with:"
        read DEST
    else
        DEST="$2"
    fi
    ln -s $DEST $LINKTMP
    rm $LINK
    mv $LINKTMP $LINK
    printf "Updated $LINK to point to new destination -> $DEST"
}

Üzgünüz, ama “cevap”, sadece sorulan soru ile uzaktan ilişkili.
user2233709

Hi @ user2233709 - Kullanıcının "Symlinks'i nasıl düzenleyebilirim? " Sorusu ilk cümlede ve bir çözüm sağlayarak açıkça cevaplandı. Detaylandırmak ister misiniz?
blizzrdof77

2
Gerçekten soruyu okudun mu? O mümkün olup olmadığını ilgili değiştirmek bir sembolik yerine yerine onu. Önerilen “çözüm”, bir sembolik bağlantının yerine geçen bir betiktir.
user2233709

0

Bağlantı adının, geçmişte yapmış olmanızın sonucu olarak var olduğunu varsayalım:

 ln -s   /the/path/to/a/file   linkname

Sonra, sembolik bağlantıyı değiştirmenin üç yolu vardır:

  • -fDizinler için zorla ve hatta kullanın -n(inode yeniden kullanılabilir):

    ln -sfn /some/new/path linkname
    
  • Sembolik bağlantıyı kaldırın ve yeni bir tane oluşturun (dizinler için bile):

    rm linkname; ln -s /some/new/path linkname
    
  • yeni bir sembolik bağlantı oluşturun, sonra mvo (dizinler için bile atomik değişiklik):

    ln -s  /some/new/path newlinkname
    mv -fT newlinkname linkname             # linkname remains after the command
    
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.