如何检查$ PWD是否为给定路径的子目录


Answers:


26

如果要可靠地测试目录是否是另一个目录的子目录,则不仅需要字符串前缀检查。Gilles的答案详细描述了如何正确执行此测试。

但是,如果您确实希望进行简单的字符串前缀检查(也许您已经对路径进行了标准化?),那么这是一个很好的选择:

test "${PWD##/home/}" != "${PWD}"

如果$PWD以“ / home /”开头,则它在左侧被剥离,这意味着它与右侧不匹配,因此“!=“返回true。


1
+1完美,在更一般的情况下:[ "${PWD##$VAR}" != "$PWD" ]如果这是一个[code-golf](stackoverflow.com/questions/tagged/code-golf)问题,您将被两个字符击败;-)更具可读性...
Tobias Kienzler

FWIW,这可能也很有用:${PWD/#$HOME/\~}
user1338062

好吧,但是PWD =“ / home /../ etc /”怎么样
Alexis Peters

1
@AlexisPeters:您是对的:我专注于问题的“字符串前缀”部分,并且我进行了编辑以使其更加清楚。Gilles很好地介绍了检查子目录的正确方法。
詹德

1
使用"${PWD%%/subdir*}"来检测用户当前是否处于subdir或在一个子目录subdir,因为从字符串,而不是开始的结束%%捕获。这对于任何需要有关参数替换的详细信息的人都应该是有用的:tldp.org/LDP/abs/html/parameter-substitution.html
George Pantazes,

33

要在任何Bourne样式的shell中测试字符串是否是另一个的前缀:

case $PWD/ in
  /home/*) echo "home sweet home";;
  *) echo "away from home";;
esac

后缀或子字符串测试使用相同的原理。请注意,在case结构中,与文件名不同,它*匹配任何字符,包括a /或initial .

在实现[[ … ]]语法的shell (即bash,ksh和zsh)中,可以使用它来将字符串与模式进行匹配。(请注意,该[命令只能测试字符串是否相等。)

if [[ $PWD/ = /home/* ]]; then 

如果要专门测试当前目录是否在下面/home,则由于符号链接,仅进行简单的子字符串测试是不够的。

如果/home是自己的文件系统,请测试当前目录(.)是否在该文件系统上。

if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
  echo 'The current directory is on the /home filesystem'
fi

如果您具有NetBSD,OpenBSD或GNU(即Linux)readlink,则可以用来readlink -f从路径中剥离符号链接。

case $(readlink -f .)/ in $(readlink -f /home)/*) 

否则,您可以使用pwd显示当前目录。但是,如果外壳程序跟踪cd命令并保留用于访问目录的名称而不是其“实际”位置,则必须注意不要使用内置的外壳程序。

case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
  "$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) 

+1感谢您详尽的回答。我在问这个问题时没有考虑链接和文件系统的特殊性,但是一定很高兴知道
Tobias Kienzler 2011年

8

原始版本:

[ ${PWD:0:6} = "/home/" ]

缺点是必须首先计算字符而无法用/home/一般的东西代替$1

编辑(感谢@Michael)以进行泛化以与$VAR一个人进行比较

[ "${PWD:0:${#VAR}}" = $VAR ]

4
${#var}是的长度$var,因此您可以将其概括为[ "${PWD:0:${#1}}" = "$1" ]
Michael Mrozek

@Michael Mrozek♦:谢谢,作品完美:)
Tobias Kienzler 2011年

2

我不太清楚这个问题,但是要找到$ PWD的父对象,请执行dirname $PWD。要找到父母的父母,请运行dirname $(dirname $PWD),依此类推...


这只有在我知道深度的情况下才能起作用,否则我最终会遇到/。好的,我可以递归检查,但是难道不是更容易吗?
Tobias Kienzler 2011年

1
@tob如果我只知道shell编程;-)
tshepang 2011年


0

嗯,可惜[没有测试STRING1 starts with STRING2条件的选择。

您可以尝试echo $PWD | grep '^$VAR',但是当VAR包含特殊符号时,它可能会以有趣的方式失败。

awkindex功能应该可以解决问题。但是,所有这些似乎太繁重了,难以测试。


[[是否进行正则表达式,所以您可以从[[$ PWD =〜^ \ / home \ /]]开始
teknopaul

0

如果找到路径的搜索部分,我将“清空”变量:

[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.