Bir dosyanın sabit bağlantı mı yoksa sembolik bağlantı mı olduğunu belirleme


51

Bir dosyaya bir dosya adı / yolu alan ve dosyanın sembolik bir bağlantı mı yoksa sabit bir bağlantı mı olduğunu belirleyen bir kabuk betiği oluşturuyorum.

Tek şey, zor bir bağlantı olup olmadıklarını nasıl göreceğimi bilmiyorum. Test dosyası olarak kullanmak için biri sabit bağlantı, biri sembolik bağlantı olmak üzere 2 dosya oluşturdum. Fakat bir dosyanın bir kabuk betiğinde sabit bir bağlantı mı yoksa sembolik mi olduğunu nasıl belirleyebilirim?

Ayrıca, sembolik bir bağlantının hedef bölümünü nasıl bulabilirim? Diyelim ki farklı bir bölüme bağlanan bir dosyam var, o orijinal dosyanın yolunu nasıl bulurum?


16
Sabit bağlantı ile ne demek istiyorsunuz? Tüm dosyalar sert linklerdir.
terdon

1
@terdon ln /foo/bar/ /foo/bar2, bir ln -s /foo/bar /foo/bar2sembolik bağlantı kurarken bir bağlantı kurar , demek istediği bu mu?
DisplayName

14
@DisplayName evet, ancak tüm dosyalar kendi inode'larına sabit linkler. Linux dosya sistemleri böyle çalışır. Örneğinizde bar2ve barher ikisi de aynı bağlantıya işaret eden sert bağlantılardır.
terdon

10
@DisplayName evet, diğer inode'lara sabit bağlantılar . Burada hiçbir çelişki yoktur. Bir dosya bir inode için bir link. Dosyanın tanımı budur. Sizin durumunuzda, bu bağlantıları farklı yerlerde bulunduruyorsunuz, ancak bu temel veri yapısını değiştirmiyor. Benim demek hem olmasıdır barve bar2aynı derecede önemlidir. Biri diğerine bir bağlantı değil, ikisi de bağlantı, ancak aynı inode'u işaret ediyor.
Terdon

3
@Scott hayır, normal dosyaların hardlink olduğunu ve oluşturulan hardlinklerin lnnormal dosyalardan farklı olmadığını söylüyorum .
terdon

Yanıtlar:


42

Kullanarak: Jim'in cevabı bir sembolik bağ test etmek açıklar tests' -Ltesti.

Ancak bir "sabit link" için test yapmak, kesinlikle istediğinizi değil. Sabit bağlantılar, Unix'in dosyaları nasıl kullandığı nedeniyle çalışır: her dosya tek bir inode ile temsil edilir. Daha sonra tek bir inode, sıfır veya daha fazla isim veya dizin girişine veya teknik olarak sert bağlantılara ("dosya" dediğiniz şey) sahiptir.

Neyse ki, bu statkomut, mümkün olduğunda, bir inode öğesinde kaç tane isim olduğunu söyleyebilir.

Yani, bunun gibi bir şey arıyorsun (burada GNU’yu veya meşgul kutusu uygulamasını varsayarak stat):

if [ "$(stat -c %h -- "$file")" -gt 1 ]; then
    echo "File has more than one name."
fi

-c '%h'Biraz anlatır statyani inode'a sadece çıkış sabit bağlantılarını sayısını, dosya vardır isimlerin sayısı için. -gt 1sonra 1'den fazla olup olmadığını kontrol eder.

Ayrıca, diğer dosyalarda olduğu gibi sembolik bağlantıların da birkaç dizine bağlanabileceğini ve böylece bir sembolik bağlantıda birkaç hardlinkin bağlanabileceğini unutmayın.


Tamam, açık olmak gerekirse, dosyanın stat komutunu kullandığı hardlinks sayısını çıkarabilirim ve eğer 1'den büyükse, o zaman bölüme bir yere bağlı başka bir dosyaya sahip olabilir.
k-Rocker

@ k-Rocker Evet. Sonra bölüm üzerinde bir yerde ikinci bir adı vardır.
derobert

1
OS X veya * BSD'de öyle stat -f %l /path/to/file. Ayrıca gstat -c %h /path/to/file, GNU coreutils'inin varsayılan isimleri olmadan (OS X üzerinde Homebrew ile) kurulu olup olmadığını kullanabilirsiniz .
GDP2

29

Bir örnek:

$ touch f1
$ ln f1 f2
$ ln f1 f3
$ ln -s f1 s1
$ ln -s f2 s2
$ ln -s ./././f3 s3
$ ln -s s3 s4
$ ln s4 s5
$ ls -li
total 0
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f3
10802345 lrwxrwxrwx 1 stephane stephane 2 Nov 12 19:56 s1 -> f1
10802346 lrwxrwxrwx 1 stephane stephane 2 Nov 12 19:56 s2 -> f2
10802347 lrwxrwxrwx 1 stephane stephane 8 Nov 12 19:56 s3 -> ./././f3
10802384 lrwxrwxrwx 2 stephane stephane 2 Nov 12 19:56 s4 -> s3
10802384 lrwxrwxrwx 2 stephane stephane 2 Nov 12 19:56 s5 -> s3

f1, f2Ve f3dizin girişleri aynı dosya (aynı inode: 10802124, sen sayısını fark edeceksiniz olan bağlantıları olan 3). Aynı düzenli dosyaya sert bağlantılar vardır .

s4ve s5aynı dosyadır (10802384). Bunlar düzenli değil, sembolik bağlantı tipindedir . Burada bir yola işaret ediyorlar . Çünkü ve aynı dizinin girişleri olduğundan , göreceli yol her ikisi için de aynı dosyaya (inod 10802347'ye sahip olan) işaret eder.s3s4s5s3

Bunu yaparsanız ls -Ll, bu, sembolik bağlantıları çözdükten sonra dosya bilgilerini almak istiyor:

$ ls -lLi
total 0
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f3
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s3
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s4
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s5

Hepsinin aynı dosyaya çözümlendiğini göreceksiniz (10802124).

Bir dosyanın sembolik bağlantı olup olmadığını kontrol edebilirsiniz [ -L file ]. Benzer şekilde, bir dosyanın normal bir dosya olup olmadığını test edebilirsiniz [ -f file ], ancak bu durumda kontrol, sembolik bağlantıları çözüldükten sonra yapılır.

hardlinkler bir dosya tipi değildir, sadece bir dosya için farklı isimlerdir (herhangi bir türde).


19

Komutun -hand -Loperatörlerini kullanarak test:

-h file 
true if file is a symbolic link

-L file 
true if file is a symbolic link

http://www.mkssoftware.com/docs/man1/test.1.asp

Bu SO iş parçacığına göre , aynı davranışa sahip, ancak -Ltercih edilir.


Tamam serin, ama ya sert bağlantılar? Sırtı kontrol ettim, ama sert bağlantılar hakkında hiçbir şey yok. -L yanlış dönerse, bunun zor bir bağlantı olduğu anlamına mı geliyor? ya da sadece normal bir dosya?
k-Rocker

1
Sabit bağlantılar aynı paylaşır inode. Ayrıca, yumuşak bağlantılar çıktısının lbaşlangıcını gösteriyor ls -l... Bu kuralları bir komut dosyasında bir araya getirebileceğinizi [[ -L file ]]ve verilen dosyanın yumuşak mı yoksa zor mu olduğunu görmek için bir test oluşturabileceğinizi düşünüyorum .
jimm-cl

Tamam, sembolik bağlantının hedef bölümünü nasıl bulabilirim?
k-Rocker

3

Burada oldukça doğru cevaplar var ama kimsenin orijinal yanlış algılamayı gerçekten ele aldığını sanmıyorum. Asıl soru temel olarak "sembolik bir bağlantı kurduğumda, daha sonra tanımlamak kolaydır. Ancak sert bir bağlantıyı nasıl tanımlayacağımı bulamıyorum." Ve evet, cevaplar temelde “yapamazsınız” ifadesine dayanıyor ve az ya da çok nedenini açıklıyor, ama hiç kimse bunun gerçekten kafa karıştırıcı ve garip olduğunu kabul etmiyor gibi görünüyor.

Tüm bunları okuyorsanız ve neler olduğunu çözdüyseniz, o zaman iyisiniz; benim küçük parçamı okumana gerek yok. Hala kafanız karıştıysa, devam edin.

Gerçekten çok kısa cevap, sabit bir bağlantının sembolik bir bağlantının değil, bir bağlantının olmadığıdır. Dizin yapısında, orijinal dizin girişinin yaptığı aynı bayt grubuna işaret eden yeni bir giriştir ve bir kez oluşturduğunuzda, tıpkı 'gerçek' ve birincisi gibi meşru olur. Sürücünüzdeki her "normal" dosyada en az bir tane sabit bağlantı vardır; Bu olmadan, içeri görmüyorum herhangidizine bakın ve başvuruda bulunamaz veya kullanamaz. Yani, eğer Fred.txt dosyanız varsa ve Wilma.txt ve Barney.txt dosyasını ona bağlarsanız, her üç isim de (ve dizin girişleri) aynı dosyaya atıfta bulunur ve hepsi de aynı şekilde geçerlidir. İşletim sisteminin metin editörünüzde "kaydet" düğmesine bastığınızda girişlerden birinin oluşturulduğunu ve diğerlerinin "ln" komutuyla yapıldığını söylemesinin bir yolu yoktur.

OS gelmez olsa çok farklı girişler aynı dosyayı işaret nasıl takip etmek zorunda. Wilma.txt dosyasını silerseniz, sürücünüzde boş yer bırakmamanız şaşırtıcı değildir. Ancak Fred.txt dosyasını silerseniz ('orijinal' dosya), hala Fred.txt olarak bilinen sürücüdeki veriler yine de Barney.txt olduğundan, sürücünüzde hiç yer boşaltmazsınız. Yalnızca tüm dizin girişlerini sildiğinizde , işletim sistemi verilerin işgal ettiği alanı tahsis eder.

Eğer Barney.txt sembolik bir bağlantı olsaydı , Fred.txt 'yi silmek boşluğu ayırırdı ve Barney.txt şimdi bozuk bir bağlantı olurdu. Ayrıca, üzerinde sembolik bir bağlantıya sahip bir dosyayı taşır veya yeniden adlandırırsanız, bağlantıyı kesersiniz. Ancak, sabitlenmiş bir dosyayı, dosya / veriye işaret eden diğer dizin girişlerini bozmadan istediğiniz şekilde taşıyabilir veya yeniden adlandırabilirsiniz, çünkü bunların tümü, sürücüdeki aynı veri bloğuna başvuran dizin girişleridir ( Bu veri inode).

[İki yıl sonra, ve o son bit karıştı bana bir dakika, bu yüzden ben açıklamak düşünüyorum. "Mv ./Wilma.txt ../elsewhere/Betty.txt" yazarsanız, dosyayı taşıyor gibi görünüyorsunuz, ama aslında değilsiniz. Yaptığınız şey, bir satır öğesini geçerli dizininizin dizin listesinden çıkarmasıdır, "Wilma.txt" adı "inode" kullanılarak bulunan verilerle ilişkilendirilir. #, "ve dizinin dizin listesine yeni bir satır öğesi ekleyerek" / "adıyla Betty.txt ismi yazıyor, inode #######. Bu nedenle, 2 gigabaytlık bir dosyayı 2 kilobaytlık bir dosya kadar hızlı bir şekilde, aynı sürücüdeki başka bir konuma taşıdığınız sürece 'taşıyabilirsiniz'.

OS aynı veri yığın işaret kaç farklı dizin girişleri takip etmek olduğundan, sen yapabilirsiniz belirli bir dosya sert bağlanmıştır eğer kesin söyleyemem rağmen anlatmak dizin girdisi olduğunu eğer 'Orijinal' bir bakıyor ya da değil bakıyor. Bunun bir yolu "ls" komutu, özellikle de "ls -l" (bu, tire işaretinden sonraki küçük harf L'dir).

Daha önceki bir örneği ödünç almak ...

 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1

İlk harf bir çizgidir, bu yüzden bir dizin ya da egzotik bir şey değil, 'normal' sıradan bir dosyadır. Fakat eğer gerçekten sıradan olsaydı, rwx-ish bölümünden sonra gelen bu sayı, "bu veri bloğuna işaret eden bir dizin girişi var." Ancak bu, sert bağlantıların gösterisinin bir parçası olduğu için "3" yazıyor.

Bunun garip ve gizemli davranışlara yol açabileceğini unutmayın (eğer başınızı sert bağlantıların etrafına sarmazsanız, yani). Fred.txt’yi metin editörünüzde açar ve bazı değişiklikler yaparsanız, Wilma.txt ve Barney.txt’te de aynı değişiklikleri görecek misiniz? Olabilir. Muhtemelen. Metin editörünüz orijinal dosyayı açıp değişiklikleri üzerine yazarak değişiklikleri kaydederse, o zaman evet, yine de üç isim de aynı (yeni değiştirilmiş) metni gösterecektir. Ancak metin editörünüz yeni bir dosya (Fred-new-temp.txt) yaratırsa, değiştirilmiş versiyonunuzu buna yazar, sonra Fred.txt'yi siler, sonra Fred-new-temp.txt'i Fred.txt olarak değiştirir, Wilma ve Barney hala değiştirilen yeni sürümü değil, orijinal sürümü işaret ediyor. Sert bağlantıları anlamadıysanız, bu sizi biraz kızdırabilir. :) [Tamam, aslında şahsen hiçbir şey bilmiyorumyeni dosya / yeniden adlandırma işlemini yapan metin editörleri , ancak tam olarak bunu yapan birçok program biliyorum, o yüzden uyanık kal.]

Son bir not: 'fsck' (dosya sistemi kontrolü) 'nin kontrol ettiği şeylerden biri, sürücünüzde bir şekilde artık bir dizin girişi tarafından referans alınmayan veri blokları olup olmadığıdır. Bazen bir şeyler ters gider ve bir inode'a işaret eden tek dizin girişi silinir, ancak sürücü alanı "kullanılabilir" olarak işaretlenmez. Bu nedenle, fsck'in işlerinden biri, kayda değer bir dosya olmadığından emin olmak için tahsis edilen alanı tüm dizin girişleriyle eşleştirmektir. Bazıları bulursa, yeni dizin girişleri oluşturur ve bunları "lost + found" içine koyar.


Merak ediyorum, bu "tam olarak bunu yapan diğer programlar" nedir?
phk

@phk Özel olarak ne düşündüğünü bilmiyorum, ama bu uzun zaman alabilir ve başarısız olursa sizi belirsiz bir durumda bırakacak eylemler yapmak için yeterince yaygın bir yaklaşımdır. Örneğin, uzak bir sunucudan indirmeyi denerseniz ve sunucunun zaman aşımına uğrama şansı olduğunu biliyorsanız, bu durumda bir yaklaşım tüm içeriği geçici bir dosyaya indirmek olacaktır. Bu şekilde indirme işleminde bir şeyler ters giderse, hala orijinal dosyaya sahipsiniz.
cwallenpoole

Kesin olarak bildiğim tek program FreeHand. Çünkü kaydetme sırasında / çöküyorsa, karışık orijinal bir dosya yerine, geride geçici bir dosya kalıyor. Ama başka programlar da yaptığını gördüm; Sana şu anda belirli örnekler veremem.
Snarke

2

kullanabilirsiniz readlink FILE; echo $?. Bu bir hardlink olduğunda 1, bir linker olduğunda 0 döndürür.

Man sayfasından: "Okuma bağlantısı olarak çağrıldığında, yalnızca sembolik bağlantının hedefi yazdırılır. Belirtilen bir sembolik bağlantı değilse, okuma bağlantısı hiçbir şey yazmaz ve hatayla çıkar."

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.