Periksa apakah dua jalur mengarah ke file yang sama

12

Saya punya skrip untuk secara rekursif membuat symlink di direktori home saya ke direktori pengaturan saya, untuk menjaga file di bawah kontrol versi. Saya ingin melompati file yang sudah disinkronkan melalui direktori induk. Yaitu, jika saya memiliki file / direktori ini:

~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar

, bagaimana saya memeriksa bahwa ~ / foo / bar dan ~ / settings / foo / bar adalah file yang sama?

Sunting : Doh, beberapa menit lagi pencarian mengungkapkan jawabannya :readlink -f $path

l0b0
sumber

Jawaban:

6

Jika dua file memiliki ID perangkat dan inode yang sama, mereka file yang sama. The stattool baris perintah membuat ini mudah untuk menemukan

if [ "$(stat -c "%d:%i" FILE1)" == "$(stat -c "%d:%i" FILE2)" ]`

...

ini berfungsi untuk file yang dikaitkan atau file yang di-link.

Homolka yang kaya
sumber
5
Untuk mengikuti tautan simbolis, Anda perlu stat -L.
Gilles 'SO- stop being evil'
Seperti yang dikatakan @Gilles, tanpa tombol -L, Anda mungkin mendapatkan hasil yang salah pada beberapa distribusi
Olaseni
18

Banyak shell memiliki -efoperator untuk testbuiltin (atau sinonimnya [) untuk menguji apakah dua jalur menunjuk ke file yang sama (mengikuti tautan simbolik). Ini termasuk bash, dash, pdksh, ksh88, ksh93 dan zsh, tetapi tidak POSIX sh. Di bash, ksh atau zsh, Anda juga dapat menggunakan -efdalam [[ … ]]membangun bersyarat.

if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files
Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Menurut halaman manual saya, -ef melakukan hal yang persis sama dengan jawaban Rich Homolka.
user13852
2
@ user13852 -efmemiliki keuntungan menjadi lebih portabel (juga sedikit lebih cepat, tetapi tidak sehingga Anda akan memperhatikan sebagian besar waktu). Misalnya ia berfungsi pada * BSD, OSX, BusyBox serta Linux / Cygwin (GNU). Ini juga lebih jelas, karena melakukan persis apa yang diperlukan. Satu-satunya keuntungan yang dapat saya lihat untuk menelepon statadalah ketika Anda tidak ingin mengikuti symlink.
Gilles 'SANGAT berhenti menjadi jahat'
0

Untuk softlink (dibuat dengan ln -s), Anda dapat menggunakan realpath. Ini tidak akan bekerja untuk hardlink.

Benjamin Bannier
sumber