Diese Antwort setzt voraus, dass $1Unterverzeichnisse enthalten sein dürfen. Wenn Sie an dem einfacheren Fall interessiert sind, bei dem es $1sich um einen einfachen Verzeichnisnamen handeln sollte, lesen Sie eine der anderen Antworten.
Platzhalter werden in doppelten Anführungszeichen nicht erweitert. Da $1es sich um doppelte Anführungszeichen handelt, sind Platzhalter kein Problem.
Sowohl ../als auch Symlinks können den tatsächlichen Speicherort einer Datei verdecken . Im Folgenden werden Tests gezeigt, um festzustellen, ob sich die Datei wirklich und nicht nur scheinbar unter dem gewünschten Pfad befindet.
Neuere Systeme: mit realpath
Um herauszufinden, ob die Datei wirklich unter ist /home/charlesingalls/oder nicht, können Sie Folgendes verwenden realpath:
realpath --relative-base=/home/charlesingalls/ "/home/charlesingalls/$1" | grep -q '^/' && exit 1
Das Obige wird ausgeführt, exit 1wenn sich die von angegebene Datei an einer $1anderen Stelle als im Verzeichnis befindet /home/charlesingalls/. realpathkanonisiert den gesamten Pfad und eliminiert sowohl Symlinks als auch ../.
realpath ist Teil von GNU coreutils und sollte auf jedem Linux-System verfügbar sein.
realpatherfordert GNU Coreutils 8.15 (Jan 2012) oder besser .
Beispiele
Um zu demonstrieren, wie realpath folgt ../, um den tatsächlichen Speicherort einer Datei zu bestimmen (z. B. wird die -qOption grep weggelassen, damit die tatsächliche Ausgabe von grep sichtbar ist):
$ touch /tmp/test
$ realpath --relative-base=$HOME "$HOME/../../tmp/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Um zu demonstrieren, wie es Symlinks folgt:
$ ln -s /tmp/test ~/test
$ realpath --relative-base=$HOME "$HOME/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Ältere Systeme: mit readlink -e
readlinkist auch in der Lage, einen Pfad zu kononisieren, indem sowohl Symlinks als auch ../:
readlink -e "$HOME/test" | grep -q "^$HOME" || exit 1
Verwenden der gleichen Beispieldateien:
$ readlink -e "$HOME/../../tmp/test" | grep "$HOME" || echo FAIL
FAIL
$ readlink -e "$HOME/test" | grep "^$HOME" || echo FAIL
FAIL
Versionen von readlinksind nicht nur auf älteren GNU-Systemen verfügbar, sondern auch auf BSD.
/. Platzhalter werden nicht in Anführungszeichen interpretiert.