Этот ответ предполагает, что $1
разрешено включать подкаталоги. Если вас интересует более простой случай, когда $1
должно быть простое имя каталога, посмотрите другой ответ.
Подстановочные знаки не раскрываются в двойных кавычках. Поскольку $1
в двойных кавычках, подстановочные знаки не являются проблемой.
Обе ../
и символические ссылки могут скрыть реальное местоположение файла. Ниже показаны тесты, позволяющие определить, находится ли файл действительно, а не просто так, как мы хотим.
Новые системы: использование realpath
Что касается того, чтобы узнать, действительно ли файл находится в самом деле, находится ли он под /home/charlesingalls/
или нет, вы можете использовать realpath
:
realpath --relative-base=/home/charlesingalls/ "/home/charlesingalls/$1" | grep -q '^/' && exit 1
Вышеприведенное запускается, exit 1
если указанный файл $1
находится где-либо, кроме каталога /home/charlesingalls/
. realpath
канонизирует весь путь, устраняя как символические ссылки, так и ../
.
realpath
является частью GNU coreutils и должен быть доступен в любой системе Linux.
realpath
требуется GNU coreutils 8.15 (январь 2012 г.) или выше .
Примеры
Чтобы продемонстрировать, как realpath следует ../
для определения реального местоположения файла (например, -q
опция grep опущена, так что фактический вывод grep видим):
$ touch /tmp/test
$ realpath --relative-base=$HOME "$HOME/../../tmp/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Чтобы продемонстрировать, как следует символические ссылки:
$ ln -s /tmp/test ~/test
$ realpath --relative-base=$HOME "$HOME/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Старые системы: использование readlink -e
readlink
также способен кононизировать путь, следуя как символическим ссылкам, так и ../
:
readlink -e "$HOME/test" | grep -q "^$HOME" || exit 1
Используя те же файлы примеров:
$ readlink -e "$HOME/../../tmp/test" | grep "$HOME" || echo FAIL
FAIL
$ readlink -e "$HOME/test" | grep "^$HOME" || echo FAIL
FAIL
В дополнение к тому, что они доступны в более старых системах GNU, версии readlink
доступны в BSD.
/
. Подстановочные знаки не интерпретируются внутри кавычек.