Wie kann ich über die Befehlszeile feststellen, ob zwei Dateien fest miteinander verbunden sind? zB verlinke etwas dazu:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Wie kann ich über die Befehlszeile feststellen, ob zwei Dateien fest miteinander verbunden sind? zB verlinke etwas dazu:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Antworten:
Bei den meisten Dateisystemen¹ wird eine Datei eindeutig durch ihre Inode- Nummer bestimmt. Sie müssen also nur prüfen, ob die beiden Dateien dieselbe Inode-Nummer haben und sich auf demselben Dateisystem befinden.
Ash, ksh, bash und zsh haben ein Konstrukt, das die Prüfung für Sie durchführt: den Datei-Gleichheitsoperator -ef
.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
ls -i /path/to/file
Listet für fortgeschrittenere Fälle die Inode-Nummer einer Datei auf. df -P /path/to/file
Zeigt an, in welchem Dateisystem sich die Datei befindet (wenn sich zwei Dateien im selben Verzeichnis befinden, befinden sie sich im selben Dateisystem). Wenn Ihr System den stat
Befehl hat, kann er wahrscheinlich die Inode- und Dateisystemnummern anzeigen ( stat
variiert von System zu System, überprüfen Sie Ihre Dokumentation). Wenn Sie einen kurzen Blick auf harte Links in einem Verzeichnis werfen möchten, versuchen Sie es ls -i | sort
(möglicherweise per Pipe an awk ).
¹ Alle nativen Unix-Dateisysteme und einige andere wie NTFS, aber möglicherweise keine exotischen Fälle wie CramFS.
fileA -ef fileB
auch 0
(Erfolg) zurückgegeben wird, wenn fileA
es sich um einen Symlink fileB
handelt oder umgekehrt, oder wenn beide auf dieselbe Datei verweisen.
[ .bashrc -ef .bash/.bashrc ]
ist richtig. Ohne Kontext habe ich natürlich keine Ahnung, warum es "nicht wirklich funktioniert" hat - Sie könnten die falschen Dateien vergleichen, Sie könnten das Ergebnis nicht richtig überprüfen, Sie könnten eine Shell ohne -ef
...
[
und ist ein Synonym für test
. Aber man [
oder man test
gibt Ihnen die Manpage des externen Befehls, während fast jede Shell einen eingebauten Befehl mit leicht unterschiedlichen Optionen hat, so dass Sie diesen im Handbuch Ihrer Shell nachschlagen müssen.
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d
). Und wenn Sie unter Linux arbeiten (mit Ihrem stat
Befehl), muss Ihre Shell [ fileA -ef fileB ]
dies alles direkt erledigen. Außerdem bricht Ihr Befehl unbeabsichtigt mit Dateinamen, die Whitespace enthalten \[?*
, oder beginnt mit -
: Setzen Sie Befehlsanweisungen ( "$(stat -c %i -- "$1")"
) immer in doppelte Anführungszeichen .
function
Schlüsselwort mit einem Funktionsnamen, der (weil er einen Bindestrich enthält) gegen POSIX-Konventionen für zulässige Namen verstößt?
$1
und zu zitieren $2
. Möglicherweise möchten Sie auch die $()
Syntax anstelle von Backticks verwenden, da die Klammern deutlich machen, wo der Befehl beginnt und wo er endet, und die Verschachtelung einfacher ist.
Wie das erste Poster zeigt, können Sie unter Linux ein Skript schreiben, das auf so etwas basiert:
stat -c '%i' fileA fileB fileC
stat -c %d
). Und wenn Sie unter Linux arbeiten (mit Ihrem stat
Befehl), muss Ihre Shell [ fileA -ef fileB ]
dies alles direkt erledigen.
find(1)
Ab GNU- Version 4.2.11 können Sie auch Folgendes verwenden:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
Wenn fileA
die gleiche Datei wie fileB
dann find
druckt „Ja“ und die Bedingung wahr wird.
Im Gegensatz zur Verwendung des Gleichheitsoperators wird -ef
hierdurch ein neuer Prozess ausgelöst.