존재하지 않는 경로가 있다고 상상해보십시오.
$ ls /foo/bar/baz/hello/world
ls: cannot access /foo/bar/baz/hello/world: No such file or directory
그러나하자 말은 /foo/bar
하지 존재합니다. 그것이 baz
경로의 중단 점 인지 판단하는 빠른 방법이 있습니까?
Bash를 사용하고 있습니다.
답변
귀하와 같은 정식 경로 이름이 주어지면 다음과 같이 작동합니다.
set -f --; IFS=/
for p in $pathname
do [ -e "$*/$p" ] || break
set -- "$@" "$p"
done; printf %s\\n "$*"
이것은 완전히 존재하거나 접근 가능한 마지막 구성 요소를 통해 인쇄 $pathname
하고 각 구성 요소를 개별적으로 arg 배열에 넣습니다. 존재하지 않는 첫 번째 구성 요소는 인쇄되지 않지만에 저장됩니다 $p
.
반대로 접근 할 수 있습니다.
until cd -- "$path" && cd -
do case $path in
(*[!/]/*)
path="${path%/*}"
;; (*) ! break
esac
done 2>/dev/null && cd -
적절하게 반환되거나 $path
필요에 따라 줄어 듭니다 . 에 대한 변경 시도는 거부 /
하지만 성공하면 현재 작업 디렉토리와 stdout으로 변경되는 디렉토리가 모두 인쇄됩니다. 현재 $PWD
도 입력됩니다 $OLDPWD
.
답변
내가 가장 좋아하는 유틸리티 중 하나는 namei
, 부분 util-linux
이며 따라서 일반적으로 Linux에만 있습니다.
$ namei /usr/share/foo/bar
f: /usr/share/foo/bar
d /
d usr
d share
foo - No such file or directory
그러나 결과는 매우 구문 분석 할 수 없습니다. 따라서 누락 된 항목을 지적하려는 경우 namei
유용 할 수 있습니다.
경로에 액세스 할 때 일반적인 문제를 해결하는 데 유용합니다. 구성 요소가 링크인지 또는 마운트 포인트인지 여부와 권한을 나타내는 경로를 얻을 수 있기 때문입니다.
$ ln -sf /usr/foo/bar /tmp/
$ namei -lx /tmp/bar
f: /tmp/bar
Drwxr-xr-x root root /
Drwxrwxrwt root root tmp
lrwxrwxrwx muru muru bar -> /usr/foo/bar
Drwxr-xr-x root root /
drwxr-xr-x root root usr
foo - No such file or directory
대문자 D
는 마운트 지점을 나타냅니다.
답변
이와 같은 것 (빈칸이있는 경로 이름을 고려한) :
#!/bin/sh
explain() {
if [ -d "$1" ]
then
printf "\t%s: is a directory\n" "$1"
elif [ -e "$1" ]
then
printf "\t%s: is not a directory\n" "$1"
else
printf "\t%s: does not exist\n" "$1"
fi
}
for item in "$@"
do
last=
test="$item"
printf "testing: '%s'\n" "$item"
while [ ! -d "$test" ]
do
last="$test"
test=$(dirname "$test")
[ -z "$test" ] && break
done
if [ -n "$last" ]
then
explain "$test"
explain "$last"
else
printf "\t%s: ok\n" "$item"
fi
done
답변
경로가 절대 경로 (/로 시작)라고 가정하면 bash에 대한 대체 솔루션입니다.
#!/bin/bash
pathname="$1"
IFS='/' read -r -a p <<<"${pathname#/}"
pa="" max="${#p[@]}" i=0
while (( i<"$max" )); do
pa="$pa/${p[i++]}"
if [[ ! -e $pa ]]; then
printf 'failed at: \t"%s"\t"%s"\n' "${pa##*/}" "${pa}"
break
fi
done
$ ./script "/foo/ba r/baz/hello/world"
failed at: "hello" "/foo/ba r/baz/hello"
답변
(( dirct=$(echo ${dir}|tr "/" " "|wc -w)+1 ))
i=2
while [ ${i} -le ${dirct} ]
do
sdir=$(echo ${dir}|cut -d/ -f1,${i})
if [ ! -d ${sdir} ]
then
echo "Path is broken at ${sdir}"
fi
(( i++ ))
done
간단하지는 않지만 스크립트를 자주 사용하려는 경우 스크립트에 넣고 실행 가능하게 만들고 경로 어딘가에 붙일 수 있습니다.
주의 사항 : 어떤 레벨의 디렉토리 이름에도 space
문자 가 포함되어 있으면 작동하지 않습니다.