존재하지 않는 경로에서 레벨 상승

존재하지 않는 경로에서 레벨 상승

스크립트(bash) 파일에 다음과 같은 코드가 있습니다.

if [ ! -d $dir ]; then
    cd $dir/..
    git clone http://...
fi

물론, 쓰여진 대로 이것은 $dir존재하지 않기 때문에 작동하지 않습니다. 여기서 최상위 디렉토리를 제거하는 좋은 방법이 있습니까?

답변1

매개변수 확장을 사용하여 경로의 마지막 단계를 제거합니다. 기존 디렉터리를 찾을 때까지 루프에서 이 작업을 수행합니다.

while [[ $dir && ! -d $dir ]] ; do
    dir=${dir%/*}
done
if [[ -d $dir ]] ; then
    echo $dir exists.
fi

답변2

chkdir() for d do ${d:+:} continue
(   cd -- "$d" && d= ||
    while cd -- "${d%"${d#*/}"}." && ! {
    [ -n "${d##*/*}" ] && break
};  do  d=${d#*/}; d=${d#"${d%%[!/]*}"}; done
    pwd -P; printf "${d:+./%s\n}\n" "$d"
);  done 2>/dev/null

이것은 입력하는 모든 경로를 처리해야 하는 작은 함수입니다. 단순히 디렉터리로 직접 변경할 수 없으면 트리를 순회하려고 시도합니다. 끊어야 할 때 순환을 깨뜨립니다. 여러 매개변수를 처리합니다. 각각에 대해 디렉터리에 대한 전체 표준 경로를 인쇄하거나 가져온 내용을 인쇄합니다.그 다음에인수 경로에 남아 있는 것은 무엇이든 가능합니다. 빈 매개변수는 건너뜁니다.

이것이 실제로 작동하는 것입니다:

$ chkdir /tmp/chrome/some/nonexistent/path .. ../test *

/tmp/chrome
./some/nonexistent/path

/home/mikeserv

/home/mikeserv/test

/home/mikeserv/test
./file1

/home/mikeserv/test
./file2

/home/mikeserv/test
./file3

마지막 리디렉션을 제거 stderr하고 디버깅을 활성화하면 어떻게 작동하는지 확인할 수 있습니다.

+ chkdir .. ///tmp/.//////chrome/not/
+ : continue
+ cd -- ..
+ d=
+ pwd -P
/home/mikeserv
+ printf \n

+ : continue
+ cd -- ///tmp/.//////chrome/not/
dash: 2: cd: can't cd to ///tmp/.//////chrome/not/
+ cd -- /.
+ [ -n  ]
+ d=//tmp/.//////chrome/not/
+ d=tmp/.//////chrome/not/
+ cd -- tmp/.
+ [ -n  ]
+ d=.//////chrome/not/
+ d=.//////chrome/not/
+ cd -- ./.
+ [ -n  ]
+ d=/////chrome/not/
+ d=chrome/not/
+ cd -- chrome/.
+ [ -n  ]
+ d=not/
+ d=not/
+ cd -- not/.
dash: 3: cd: can't cd to not/.
+ pwd -P
/tmp/chrome
+ printf ./%s\n\n not/
./not/

관련 정보