/my/dir
İle aynı bölümde olup olmadığını nasıl kontrol edebilirim /
?
Bu, bir komut dosyasına entegrasyon içindir. Bağlama destekleri doğru şekilde kullanılmalıdır. POSIX uyumlu çözümlere açıktır.
/my/dir
İle aynı bölümde olup olmadığını nasıl kontrol edebilirim /
?
Bu, bir komut dosyasına entegrasyon içindir. Bağlama destekleri doğru şekilde kullanılmalıdır. POSIX uyumlu çözümlere açıktır.
Yanıtlar:
Bunu stat ile kontrol edebilirsiniz:
$ stat -c '%d %m' /proc/sys/
3 /proc
Cihaz numarasını ve dizininizin nereye takıldığını gösterir.
stat
kabuk komutu POSIX değil ...
Aşağıdaki komut, dosyayı içeren bağlama noktası için benzersiz bir ad verir $file
:
df -P -- "$file" | awk 'NR==2 {print $1}'
Bu, herhangi bir POSIX sisteminde çalışır . Bu -P
seçenek öngörülebilir bir format getirir; ikinci satırın ilk alanı “dosya sistemi adı” dır. Bu nedenle, iki dosyanın kontrol edilmesi aynı bağlama noktasının altındadır:
if [ "$(df -P -- "$file1" | awk 'NR==2 {print $1}')" = \
"$(df -P -- "$file2" | awk 'NR==2 {print $1}')" ]; then
echo "$file1 and $file2 are on the same filesystem" ; fi
Veya birkaç işlem çağrısını kaydetmek için:
if df -P -- "$file1" "$file2" |
awk 'NR!=1 {dev[NR] = $1} END {exit(dev[2] != dev[3])}'; then
echo "$file1 and $file2 are on the same filesystem" ; fi
Birkaç işletim sisteminde birim adlarında boşluk olabilir. df
Bu durumda çıktıyı ayrıştırmanın tamamen güvenilir bir yolu yoktur .
Başlık altında, tarafından st_dev
döndürülen alana göre dosya içeren dosya sistemini tanımlayabilirsiniz stat
. Bunu bir kabuk komut dosyasından yapmanın taşınabilir bir yolu yoktur. Bazı sistemlerin bir stat
yardımcı programı vardır, ancak sözdizimi değişiklik gösterir:
stat
, st_dev
alanı çağrıldığında bildirir stat -c %D -- "$file"
.stat
GNU coreutils ile uyumlu bir kurulum bulunur . Diğerleri sahip stat
olmadan %c
seçeneği; kullanabilirsiniz stat -t -- "$file" | awk '{print $8}'
ancak bu yalnızca dosya adı boşluk içermiyorsa veya stat -t -- "$file" | awk 'END {print $(NF-8)}'
rasgele dosya adları ile başa çıkıyor ancak stat
çıktının gelecekteki alan eklemeleriyle başa çıkmıyorsa çalışır .stat
yardımcı programa sahiptir stat -f %d -- "$file"
.stat
faydası yoktur .Perl mevcutsa,
perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"
ve karşılaştırmayı yapmak için:
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"
İstenen sonucun net olmadığı bazı köşe durumları olduğunu unutmayın. Örneğin, Linux'un bağlama atlarla, sonra mount --bind /foo /bar
, /foo
ve /bar
aynı dosya sistemi olarak kabul edilir. İki dosyanın aslında aynı cihazda bulunması her zaman mümkündür, ancak asla bilemezsiniz: örneğin, dosyalar iki farklı ağ montajındaysa, istemcinin sunucunun farklı dosya sistemlerini dışa aktarıp aktarmadığını bilmesinin bir yolu yoktur.
Dosyalar dizinse ve bunlara yazabiliyorsanız, başka bir yöntem geçici bir dosya oluşturmak ve sabit bir bağlantı kurmaya çalışmaktır. Bu, Linux bağlama bağlarında olumsuz bir sonuç rapor eder.
tmp1=$(TMPDIR=$dir1 mktemp)
tmp2=$(TMPDIR=$dir2 mktemp)
if ln -f -- "$tmp1" "$tmp2"; then
echo "$dir1 and $dir2 are on the same filesystem, which supports hard links"
fi
rm -f "$tmp1" "$tmp2"
df
her zamanki gibi kendisine bazen bir sembolik cihaz adını vermek değil, /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4
yapım df
değil güvenilir. Şimdiye kadar tek güvenilir seçenek, stat
tabanlı bir çözüm kullanmaktır.
df
cihaz için ad raporları ne olursa olsun , iki çağırma arasında tutarlıdır, bu nedenle karşılaştırma için sorun yoktur.
df
rapor /dev/sda6
ve /dev/disk/by-uuid/ca09b...
her ikisi de aynı cihaza, ancak farklı bağlama noktalarına atıfta bulunuyor. Her bağlama noktasından dosyalarla çalışırken dize karşılaştırma testi açıkça başarısız olur.
mount /dev/sda6 /mnt1
ardından mount /dev/sda6 /mnt2
bir cazibe gibi çalışıyor. cat /proc/mounts
onunla iyi. Ancak, yalnızca Wheezy'den beri kök dosya sistemi için aygıt olarak /dev/disk/by-uuid/ca09b...
gösterilir df
. Daha girişimler bu simlink kullanarak veya monte etmek UUID=ca09b...
sözdizimi daha başka bir şey gösteren bitmez montaj /dev/sda6
içinde df
(Ben önyükleme işlemi sırasında ne yaptığını çoğaltmak nasıl bilmiyorum ama buraya endişe değildir).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Herhangi bir sayıda yolla çalışır.
df
olan her zaman iyi bir fikir değildir .
$6
Aygıt adını ( $1
) değil, takma noktasını ( ) kontrol ediyorum , bu yüzden bir sorun olmamalı.
POSIX'te bulunan en iyi kusursuz çözüm , stat (2) işlevi tarafından sağlanan dosyaların cihaz kimliklerinin karşılaştırılmasıdır .
Perl, Gilles'in işaret ettiği gibi bir istatistik işlevine sahiptir :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
ancak "POSIX yolu" aşağıdaki gibi bir C programı kullanmaktır:
./checksamedev file1 file2
hangi kaynak kodu aşağıdaki gibidir:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
struct stat s1, s2;
if( argc==3 && lstat(argv[1], &s1)==0 && lstat(argv[2], &s2)==0 )
return !(s1.st_dev == s2.st_dev);
return 2;
}
Her iki dosyanın aygıt kimlikleri eşitse, aynı dosya sisteminde barındırılırlar, bu durumda yukarıdaki komutlar 0 değerini döndürür (aksi takdirde başka bir değer). İle kontrol edin echo $?
.
Bu, bağlama bağları ile iyi çalışır, ancak muhtemelen ağ bağlantılarıyla çalışmaz.