Esta resposta assume que $1
é permitido incluir subdiretórios. Se você estiver interessado no caso mais simples, onde $1
deve haver um nome de diretório simples, consulte uma das outras respostas.
Os curingas não são expandidos quando estiver entre aspas duplas. Como $1
está entre aspas duplas, os curingas não são um problema.
Os ../
links simbólicos e podem obscurecer a localização real de um arquivo. Abaixo, são mostrados testes para determinar se o arquivo está realmente, e não apenas aparentemente, no caminho que queremos.
Sistemas mais recentes: usando realpath
Quanto a descobrir se o arquivo é realmente se o arquivo está realmente abaixo /home/charlesingalls/
ou não, você pode usar realpath
:
realpath --relative-base=/home/charlesingalls/ "/home/charlesingalls/$1" | grep -q '^/' && exit 1
As execuções acima exit 1
se o arquivo especificado pelo $1
é em qualquer lugar que não seja sob o diretório /home/charlesingalls/
. realpath
canoniza todo o caminho, eliminando os links simbólicos e ../
.
realpath
faz parte do GNU coreutils e deve estar disponível em qualquer sistema Linux.
realpath
requer GNU coreutils 8.15 (janeiro de 2012) ou melhor .
Exemplos
Para demonstrar como o realpath segue ../
para determinar a localização real de um arquivo (por exemplo, a -q
opção grep é omitida para que a saída real do grep seja visível):
$ touch /tmp/test
$ realpath --relative-base=$HOME "$HOME/../../tmp/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Para demonstrar como segue os links simbólicos:
$ ln -s /tmp/test ~/test
$ realpath --relative-base=$HOME "$HOME/test" | grep '^/' && echo FAIL
/tmp/test
FAIL
Sistemas mais antigos: usando readlink -e
readlink
também é capaz de cononicalizar um caminho, seguindo os links simbólicos e ../
:
readlink -e "$HOME/test" | grep -q "^$HOME" || exit 1
Usando os mesmos arquivos de exemplo:
$ readlink -e "$HOME/../../tmp/test" | grep "$HOME" || echo FAIL
FAIL
$ readlink -e "$HOME/test" | grep "^$HOME" || echo FAIL
FAIL
Além de estar disponível em sistemas GNU mais antigos, versões do readlink
estão disponíveis no BSD.
/
. Os curingas não são interpretados entre aspas.