Sprawdź, czy dwie ścieżki wskazują ten sam plik

12

Mam skrypt do rekurencyjnego tworzenia dowiązań symbolicznych w moim katalogu domowym do katalogu ustawień, aby pliki były pod kontrolą wersji. Chciałbym, aby pomijał pliki, które są już dowiązane symbolicznie przez katalog nadrzędny. To znaczy, jeśli mam te pliki / katalogi:

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

, jak sprawdzić, czy ~ / foo / bar i ~ / settings / foo / bar są tym samym plikiem?

Edytuj : D'oh, kolejne kilka minut poszukiwań ujawniło odpowiedź :readlink -f $path

l0b0
źródło

Odpowiedzi:

6

Jeśli dwa pliki mają ten sam identyfikator urządzenia i i-węzeł, są to ten sam plik. statNarzędzie linii poleceń sprawia, że to łatwe do znalezienia

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

...

działa to w przypadku plików z dowiązaniami symlinkowanymi lub dowiązaniami stałymi.

Rich Homolka
źródło
5
Aby podążać za dowiązaniami symbolicznymi, potrzebujesz stat -L.
Gilles 'SO - przestań być zły'
Jak powiedział @Gilles, bez przełącznika -L możesz uzyskać błędne wyniki w niektórych dystrybucjach
Olaseni,
19

Wiele powłok ma -efoperatora testwbudowanego (lub jego synonimu [), który sprawdza, czy dwie ścieżki wskazują na ten sam istniejący plik (następujące dowiązania symboliczne). Dotyczy to bash, dash, pdksh, ksh88, ksh93 i zsh, ale nie POSIX sh. W bash, ksh lub zsh możesz także użyć -efw [[ … ]]konstrukcji warunkowej.

if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files
Gilles „SO- przestań być zły”
źródło
1
Według mojej strony -ef robi dokładnie to samo, co odpowiedź Richa Homolki.
user13852
2
@ user13852 -efma tę zaletę, że jest bardziej przenośny (również nieco szybszy, ale nie tak, abyś zauważał większość czasu). Na przykład działa na * BSD, OSX, BusyBox, a także Linux / Cygwin (GNU). Jest również jaśniejszy, ponieważ robi dokładnie to, co jest wymagane. Jedyną zaletą, którą widzę w połączeniu, statjest to, że nie chcesz podążać za dowiązaniami symbolicznymi.
Gilles „SO- przestań być zły”
0

Do softlinków (utworzonych przy pomocy ln -s) możesz użyć realpath. Nie zadziała to jednak w przypadku dowiązań twardych.

Benjamin Bannier
źródło