Jak mogę sprawdzić, czy dwa pliki są na stałe połączone z linii poleceń? np. coś to łączy:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Jak mogę sprawdzić, czy dwa pliki są na stałe połączone z linii poleceń? np. coś to łączy:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Odpowiedzi:
W większości systemów plików¹ plik jest jednoznacznie określony przez jego numer i- węzła , więc wystarczy sprawdzić, czy dwa pliki mają ten sam numer i-węzła i są w tym samym systemie plików.
Ash, ksh, bash i zsh mają konstrukcję, która sprawdza za Ciebie: operator równości plików -ef
.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
W przypadku bardziej zaawansowanych przypadków ls -i /path/to/file
wyświetla numer i-węzła pliku. df -P /path/to/file
pokazuje, na jakim systemie plików znajduje się plik (jeśli dwa pliki znajdują się w tym samym katalogu, znajdują się w tym samym systemie plików). Jeśli twój system ma stat
polecenie, prawdopodobnie może wyświetlać numery i-węzłów i systemu plików ( stat
różni się w zależności od systemu, sprawdź dokumentację). Jeśli chcesz szybko rzucić okiem na twarde linki w katalogu, spróbuj ls -i | sort
(być może potokowany do awk ).
¹ Wszystkie rodzime systemy plików unix i kilka innych, takich jak NTFS, ale prawdopodobnie nie egzotyczne przypadki, takie jak CramFS.
fileA -ef fileB
zwraca również 0
(sukces), jeśli fileA
jest dowiązaniem symbolicznym fileB
lub odwrotnie, lub oba łączą się do tego samego pliku.
[ .bashrc -ef .bash/.bashrc ]
jest poprawny. Bez kontekstu oczywiście nie mam pojęcia, dlaczego tak naprawdę „nie działało” - możesz porównywać niewłaściwe pliki, możesz nie sprawdzać wyniku poprawnie, możesz używać powłoki bez -ef
...
[
i jest synonimem test
. Ale man [
lub man test
da ci stronę podręcznika zewnętrznego polecenia, podczas gdy prawie każda powłoka ma wbudowane polecenie z nieco innymi opcjami, więc musisz to sprawdzić w podręczniku powłoki.
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d
). A jeśli korzystasz z Linuksa (biorąc pod uwagę twoje stat
polecenie), twoja powłoka musi [ fileA -ef fileB ]
to wszystko zrobić bezpośrednio. Również twoje polecenie nie działa z nazwami plików zawierającymi białe znaki lub \[?*
, lub zaczyna się od -
: zawsze umieszczaj podwójne cudzysłowy wokół polecenia susbtitutions ( "$(stat -c %i -- "$1")"
).
function
słowo kluczowe o nazwie funkcji, które (ze względu na kreskę) narusza konwencje POSIX dotyczące dozwolonych nazw?
$1
i $2
. Możesz także użyć $()
składni zamiast odwrotnych znaków, ponieważ nawiasy wyjaśniają, gdzie zaczyna się i gdzie kończy polecenie, a zagnieżdżanie jest prostsze.
Jak sugeruje pierwszy plakat, w Linuksie możesz napisać skrypt oparty na czymś takim:
stat -c '%i' fileA fileB fileC
stat -c %d
). A jeśli korzystasz z Linuksa (biorąc pod uwagę twoje stat
polecenie), twoja powłoka musi [ fileA -ef fileB ]
to wszystko zrobić bezpośrednio.
W GNU w find(1)
wersji 4.2.11 lub nowszej możesz także użyć tego:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
Jeśli fileA
jest to ten sam plik, co fileB
wtedy find
, wydrukuje „tak” i warunek się spełni.
W przeciwieństwie do korzystania z operatora równości plików -ef
spowoduje to odrodzenie nowego procesu.