Bagaimana saya bisa mengecek apakah /my/dir
ada di partisi yang sama /
?
Ini untuk integrasi dalam skrip. Bind mounts harus ditangani dengan benar. Selamat datang solusi yang kompatibel dengan POSIX.
Bagaimana saya bisa mengecek apakah /my/dir
ada di partisi yang sama /
?
Ini untuk integrasi dalam skrip. Bind mounts harus ditangani dengan benar. Selamat datang solusi yang kompatibel dengan POSIX.
Jawaban:
Anda dapat memeriksa ini dengan stat:
$ stat -c '%d %m' /proc/sys/
3 /proc
Menunjukkan nomor perangkat Anda dan tempat direktori Anda dipasang.
stat
perintah shell bukan POSIX ...
Perintah berikut memberikan nama unik untuk titik pemasangan yang berisi file $file
:
df -P -- "$file" | awk 'NR==2 {print $1}'
Ini berfungsi pada sistem POSIX apa pun . The -P
pilihan membebankan format diprediksi; bidang pertama dari baris kedua adalah "nama sistem file". Jadi, untuk memeriksa dua file berada di bawah titik pemasangan yang sama:
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
Atau, untuk menyimpan beberapa proses pemanggilan:
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
Beberapa sistem operasi dapat memiliki ruang dalam nama volume. Tidak ada cara yang sepenuhnya dapat diandalkan untuk mengurai df
output dalam kasus ini.
Di bawah tenda, Anda dapat mengidentifikasi sistem file yang berisi file menurut st_dev
bidang yang dikembalikan oleh stat
. Tidak ada cara portabel untuk melakukan ini dari skrip shell. Beberapa sistem memiliki stat
utilitas, tetapi sintaks bervariasi:
stat
melaporkan st_dev
bidang ketika dipanggil sebagai stat -c %D -- "$file"
.stat
yang kompatibel dengan GNU coreutils. Lain memiliki stat
tanpa %c
pilihan; Anda dapat menggunakan stat -t -- "$file" | awk '{print $8}'
tetapi ini hanya berfungsi jika nama file tidak mengandung spasi, atau stat -t -- "$file" | awk 'END {print $(NF-8)}'
yang mengatasi dengan nama file yang sewenang-wenang tetapi tidak dengan penambahan bidang di masa depan untuk stat
output.stat
utilitas berbeda yang membutuhkan stat -f %d -- "$file"
.stat
utilitas.Jika Perl tersedia, Anda dapat menggunakan
perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"
dan untuk melakukan perbandingan:
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"
Perhatikan bahwa ada beberapa kasus sudut di mana hasil yang diinginkan tidak jelas. Sebagai contoh, dengan bind mount Linux, setelahnya mount --bind /foo /bar
, /foo
dan /bar
dianggap sebagai sistem file yang sama. Selalu dimungkinkan bahwa kedua file tersebut sebenarnya terletak pada perangkat yang sama tetapi Anda tidak akan pernah tahu: misalnya, jika file berada di dua tunggangan jaringan yang berbeda, klien tidak memiliki cara untuk mengetahui apakah server mengekspor sistem file yang berbeda.
Jika file tersebut adalah direktori dan Anda dapat menulisnya, metode lain adalah membuat file sementara dan berusaha membuat tautan keras. Yang ini melaporkan hasil negatif di seluruh mount mengikat Linux.
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
tidak selalu memberikan nama perangkat, tetapi kadang-kadang symlink /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4
membuatnya df
tidak dapat diandalkan. Satu-satunya pilihan yang dapat diandalkan sejauh ini adalah menggunakan stat
solusi berbasis.
df
melaporkan untuk perangkat, itu konsisten antara dua doa, jadi tidak apa-apa untuk perbandingan.
df
laporan /dev/sda6
dan /dev/disk/by-uuid/ca09b...
, keduanya merujuk ke perangkat yang sama, tetapi titik pemasangan berbeda. Uji perbandingan string jelas gagal ketika mencoba dengan file dari setiap titik pemasangan.
mount /dev/sda6 /mnt1
diikuti oleh mount /dev/sda6 /mnt2
karya-karya seperti pesona. cat /proc/mounts
tidak masalah dengan itu. Namun, hanya sejak Wheezy yang /dev/disk/by-uuid/ca09b...
ditampilkan df
sebagai perangkat untuk sistem file root. Upaya lebih lanjut untuk memasangnya menggunakan simlink ini atau UUID=ca09b...
sintaks mount tidak berakhir menunjukkan apa pun selain /dev/sda6
di df
(saya tidak tahu bagaimana mereproduksi apa yang dilakukan selama proses boot, tapi itu bukan masalah di sini).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Bekerja dengan sejumlah jalur.
df
adalah tidak selalu ide yang baik .
$6
), bukan nama perangkat ( $1
), sehingga seharusnya tidak menjadi masalah.
Solusi terbaik yang tersedia di POSIX adalah perbandingan ID perangkat file yang disediakan oleh fungsi stat (2) .
Perl memiliki fungsi stat yang sama dengan yang ditunjukkan Gilles :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
tetapi "cara POSIX" adalah menggunakan program C seperti:
./checksamedev file1 file2
kode sumber yang mana adalah sebagai berikut:
#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;
}
Jika ID perangkat kedua file sama, mereka dihosting di sistem file yang sama, dalam hal ini, perintah di atas mengembalikan 0 (nilai lain jika tidak). Periksa dengan echo $?
.
Ini berfungsi baik dengan bind mounts, tapi mungkin tidak dengan network mounts.