该答案假定$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年1月)或更高版本。
例子
为了演示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 上还可以使用的版本。
/
。不能在引号内解释通配符。