Cette réponse suppose qu'il $1
est autorisé d'inclure des sous-répertoires. Si vous êtes intéressé par le cas le plus simple où $1
devrait être un simple nom de répertoire, consultez l'une des autres réponses.
Les caractères génériques ne sont pas développés lorsqu'ils sont entre guillemets. Comme $1
c'est entre guillemets, les caractères génériques ne sont pas un problème.
Les deux ../
et les liens symboliques peuvent masquer l' emplacement réel d'un fichier. Ci-dessous sont des tests pour déterminer si le fichier est vraiment, pas seulement en apparence, sous le chemin que nous voulons.
Systèmes plus récents: utilisation realpath
Quant à savoir si le fichier est vraiment /home/charlesingalls/
ou non, vous pouvez utiliser realpath
:
realpath --relative-base=/home/charlesingalls/ "/home/charlesingalls/$1" | grep -q '^/' && exit 1
Ce qui précède s'exécute exit 1
si le fichier spécifié par se $1
trouve ailleurs que sous le répertoire /home/charlesingalls/
. realpath
canonise l'ensemble du chemin, en éliminant les liens symboliques et ../
.
realpath
fait partie de GNU coreutils et devrait être disponible sur n'importe quel système Linux.
realpath
nécessite GNU coreutils 8.15 (janvier 2012) ou mieux .
Exemples
Pour montrer comment realpath suit ../
pour déterminer l'emplacement réel d'un fichier (par exemple, l' -q
option grep est omise pour que la sortie réelle de grep soit visible):
$ touch /tmp/test
$ realpath --relative-base=$HOME "$HOME/../../tmp/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Pour montrer comment il suit les liens symboliques:
$ ln -s /tmp/test ~/test
$ realpath --relative-base=$HOME "$HOME/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Systèmes plus anciens: utilisation readlink -e
readlink
est également capable de cononicaliser un chemin, en suivant à la fois les liens symboliques et ../
:
readlink -e "$HOME/test" | grep -q "^$HOME" || exit 1
En utilisant les mêmes fichiers d'exemple:
$ readlink -e "$HOME/../../tmp/test" | grep "$HOME" || echo FAIL
FAIL
$ readlink -e "$HOME/test" | grep "^$HOME" || echo FAIL
FAIL
En plus d'être disponibles sur les anciens systèmes GNU, des versions de readlink
sont disponibles sur BSD.
/
. Les caractères génériques ne sont pas interprétés entre guillemets.