Answers:
给定一个规范的路径名(例如您的路径名),它将起作用:
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。
$IFS。这就是它的工作原理。它不会进行路径名扩展,只是在此处调用的变量$pathname被扩展为拆分为的路径组件数组$IFS。
                    ns,如果在这里使用它,将使讨论变得毫无意义。
                    我最喜欢的工具之一是的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表示安装点。
namei只要给它提供了一条存在的路径,它就可以为我工作,但是当我给它提供一条不存在的路径时,它就可以工作namei: failed to stat: /usr/share/foo/bar: No such file or directory。
                    这样的事情(用嵌入的空格来解释路径名):
#!/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
donecd not_a_directoryshell,只会向stderr写像这样的东西cd:cd:6: no such file or directory: not_a_directory。实际上,用户的外壳将以用户可能已经非常熟悉的格式进行操作。无论如何,最终它几乎总是更容易和更好,只是做一些事情并让Shell根据需要处理报告。但是,这种哲学确实需要非常严格地关注返回值及其提升/保存。
                    假设路径是绝对路径(以/开头),则是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"pa为pa_prevwhile循环的第一行(在它递增之前)。如果对“ pa”的测试失败,pa_prev则在给定路径中具有最后一个现有目录。
                    (( 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字符,则此操作将无效。
access(2)不是很精细,因此解决方案通常涉及编写一些东西来依次迭代和测试每个路径元素……