$ PWD가 주어진 경로의 하위 디렉토리인지 확인하는 방법


25

예를 들어 $PWD/ home의 하위 디렉토리 인지 확인하십시오 . 즉, 한 문자열이 다른 문자열로 시작하는지 확인하기 위해 bash 문자열 작업을 찾고 있습니다.

답변:


26

디렉토리가 다른 디렉토리의 하위 디렉토리인지 여부를 확실하게 테스트하려면 문자열 접두어 검사 이상이 필요합니다. Gilles의 답변은이 테스트를 올바르게 수행하는 방법을 자세히 설명합니다.

그러나 간단한 문자열 접두사 검사를 원한다면 (이미 경로를 정규화 했습니까?) 좋은 방법입니다.

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

경우 $PWD"/ 홈 /"로 시작, 그것은이 "! ="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는 하위 디렉토리를 확인하는 적절한 방법을 훌륭하게 다루었습니다.
Jander

1
%%이 (가) 시작 대신 문자열 끝에서 캡처하므로 "${PWD%%/subdir*}"사용자가 현재 subdir의 하위 디렉토리에 있는지 또는 하위 디렉토리에 있는지 여부를 감지하는 데 사용 합니다 subdir. 이것은 매개 변수 대체에 대한 자세한 정보를 찾는 사람에게 유용합니다. tldp.org/LDP/abs/html/parameter-substitution.html
George Pantazes

33

Bourne 스타일 쉘에서 문자열이 다른 접두어인지 테스트하려면 다음을 수행하십시오.

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

접미사 또는 부분 문자열 테스트에도 동일한 원칙이 적용됩니다. 에 있습니다 case구조, 파일 이름과는 달리, *을 포함한 모든 문자와 일치 /또는 초기을 ..

[[ … ]]구문 을 구현하는 쉘 (예 : 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

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

2

내가 너무 잘 질문을 이해하지 않지만,의 부모 찾기 위해 $ PWD를 수행합니다 dirname $PWD. 부모의 부모를 찾으려면 다음을 실행하십시오 dirname $(dirname $PWD).


그것은 깊이를 알고있는 경우에만 작동합니다 /. 그렇지 않으면 나는로 끝납니다 . 좋아, 재귀 적으로 확인할 수는 있지만 더 쉬운 것이 없습니까?
Tobias Kienzler

1
@tob 쉘 프로그래밍 만 알고 있다면 ;-)
tshepang


0

흠, [테스트 STRING1 starts with STRING2조건 이없는 것은 유감입니다 .

시도해 볼 수도 echo $PWD | grep '^$VAR'있지만 VAR특수 기호 가 포함되어 있으면 흥미로운 방식으로 실패 할 수 있습니다 .

awkindex기능은 트릭을 수행 할 수 있어야합니다. 그러나이 모든 것이 테스트하기에 너무 무거워 보입니다.


[[정규 표현식을 사용하므로 [[$ PWD = ~ ^ \ / home \ /]]로 시작하십시오.
teknopaul 23.

0

경로의 검색 된 부분을 찾으면 변수를 "비 웁니다".

[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.