Bash에서 PATH와 같은 변수를 사용하여 검색하는 방법

Bash에서 PATH와 같은 변수를 사용하여 검색하는 방법

찾을 수 없는 경우를 대비해 내가 CDPATH원하는 경로가 있다고 가정해 보겠습니다.cd.

자체를 사용 cd하지 않고 이를 만족하는 첫 번째 경로를 얻는 방법은 무엇입니까?bash

목적은 적어도 내가 사용하고 있는 이 버전의 bash에서는 지원되지 않도록 cd하는 것 입니다. 하지만 다른 bash에서도 작동합니다.pushdpushdCDPATH

답변1

사용에 대한 우려 사항이 cd있는 경우실제로cd현재 셸의 작업 디렉터리 이동과 관련하여 무해하게 사라지는 하위 셸에서 실행되는 명령 대체를 사용할 수 있습니다 .

d=$(cd some-name)

예를 들어:

$ mkdir /tmp/{a..d}
$ CDPATH=/tmp
$ cd /
$ pwd
/
$ dir=$(cd c)
$ printf '%s\n' "${dir%/*}"
/tmp
$ pwd
/

cd c여기에서는 가설의 항목이 이를 만족하는 경우 출력을 캡처합니다 CDPATH. 결과는 새 작업 디렉터리이므로 해당 디렉터리에서 해당 경로 항목을 반환하기 위해 CDPATH매개변수 확장을 사용하여 마지막 슬래시(기본적으로 가장 깊은 디렉터리의 이름)를 제거합니다. 위와 /tmp/c같은 모양이 됩니다 /tmp.

답변2

당신이 의미한다고 가정

특정 값이 주어지면 $CDPATH어느 디렉터리로 이동하게 되나요? cd foo를 사용하지 않고도 찾을 수 있나요 cd?

좋습니다. 설정 cd foo되면 각각 분리된 값을 조사하여 이름이 지정된 하위 디렉터리를 찾습니다 .$CDPATH:$CDPATHfoo

#!/bin/bash

dir=$1
cdpath=${2:-$CDPATH}

if [ -z "$cdpath" ] && [ -d "$dir" ]; then
    printf '"cd %s" would take you to %s\n' "$dir" "$dir"
    exit
elif [[ $dir == /* ]] || [[ $dir == ./* ]] || [[ $dir == ../* ]]; then
    # special cases where $CDPATH is not used
    if [ -d "$dir" ]; then
        printf '"cd %s" would take you to %s (ignoring $CDPATH)\n' "$dir" "$dir"
        exit
    else
        printf 'Did not find destination directory for %s\n' "$dir"
        exit 1
    fi
fi

while [ -n "$cdpath" ]; do
    subdir=${cdpath%%:*}/$dir
    if [ -d "$subdir" ]; then
        printf '"cd %s" would take you to %s\n' "$dir" "$subdir"
        exit
    fi
    [[ $cdpath != *:* ]] && break
    cdpath=${cdpath#*:}
done

printf 'Did not find destination directory for %s\n' "$dir"
exit 1

스크립트는 두 번째 인수(또는 해당 환경)로 지정된 변수 값을 보고 스크립트 명령줄에서 첫 번째 인수로 지정된 경우 대상 디렉터리가 어디로 이동하는지 CDPATH파악하려고 시도합니다 .cd

~부터CDPATH 수출하면 안 된다, 스크립트는 다음 중 하나로 호출되어야 합니다.

CDPATH=$CDPATH ./script.sh dir-name

또는

./script.sh dir-name "$CDPATH"

스크립트는 먼저 $CDPATH비어 있는지 테스트합니다. 그렇다면 현재 디렉토리로 cd dir이동합니다 . dir또한 사용을 위해 우회해야 하는 몇 가지 특수한 경우도 처리합니다 $CDPATH.

비어 있지 않으면 $CDPATH스크립트는 해당 값에서 요소를 하나씩 선택하기 시작하여 지정된 디렉터리가 언급된 경로의 하위 디렉터리로 존재하는지 확인합니다.

:해당 값의 첫 번째 값부터 끝까지 제거하여 $cdpath첫 번째 값을 선택합니다 . $cdpath나중에 처음 얻은 값까지 삭제하도록 설정합니다 :. 이렇게 하면 루프가 경로를 반복하고 $cdpath유효한 디렉토리가 발견되거나 궁극적으로 문자열에 더 이상 문자가 없는 경우에만 종료됩니다.:

루프를 벗어나면 유효한 목적지를 찾을 수 없습니다 cd.

참고: 내 코드는 모든 경우를 처리할 수 없습니다. 관련 비트를 참조하십시오.POSIX 표준.

답변3

명령은 어떻습니까?

 $ find `echo $CDPATH|sed 's/://'` -name 'whatever' -print

관련 정보