Этот ответ предполагает, что $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.
/. Подстановочные знаки не интерпретируются внутри кавычек.