如何在路径名中将“..”转换为bash脚本中的绝对名称?

时间:2011-07-10 21:34:00

标签: linux bash unix

如何将路径名中的..转换为bash脚本中的绝对路径名。也就是说,如果我有路径/home/nohsib/dvc/../bop,我希望将其更改为不包含点的路径,在这种情况下/home/nohsib/bop

我该怎么做?

10 个答案:

答案 0 :(得分:47)

您要找的是 readlink

absolute_path=$(readlink -m /home/nohsib/dvc/../bop)

请注意:您需要使用提供“-m”选项的GNU readlink实现。例如,BSD的readlink没有。

答案 1 :(得分:33)

尝试:

ABSOLUTE_PATH=$(cd /home/nohsib/dvc/../bop; pwd)

答案 2 :(得分:8)

使用的一个问题:

ABSOLUTE_PATH=$(cd ${possibleDirectory}; pwd)

如果$ {possibleDirectory}不存在,那么ABSOLUTE_PATH将被设置为当前目录。这可能不是你想要或期望的。

我认为使用这个版本可能更为可取:

ABSOLUTE_PATH=$(cd ${possibleDirectory} && pwd)

如果$ {possibleDirectory}不存在或无法访问,由于缺少目录访问权限,ABSOLUTE_PATH将包含空字符串。

这样做的好处是,您可以测试空字符串或让它自然失败,具体取决于具体情况。在发生故障' cd'的情况下默认为当前目录。命令可能导致非常意外且可能是灾难性的结果(例如rm -rf" $ ABSOLUTE_PATH")

答案 3 :(得分:3)

使用

echo Absolute path: $(cd $1; pwd)

答案 4 :(得分:3)

如果您想在不遵循任何符号链接的情况下执行此操作,请尝试使用带有src选项的realpath

-s

请注意,对于$ realpath -s /home/nohsib/dvc/../bop /home/nohsib/bop ,通常除了最后一个组件之外的所有组件都必须存在。因此,为了使上述工作正常,文件系统中必须存在以下内容:

realpath

但您可以使用/home /home/nohsib /home/nohsib/dvc 选项绕过该要求。

-m

(注意$ realpath -sm /home/nohsib/dvc/../bop /home/nohsib/bop 并非在所有系统上都可用,尤其是较旧的非Debian系统。对于那些在嵌入式Linux上工作的人,不幸的是Busybox realpath不支持realpath-s开关。)

答案 5 :(得分:1)

另外需要注意的是,如果当前路径位于符号链接下,则可以使用此解析真实路径:

pwd -P

要解决您的具体问题,这将发出cd命令将目录更改为路径,而不包含“..”。请注意,您将使用正确的路径位于同一文件夹中:

cd `pwd -P`

答案 6 :(得分:0)

作为GNU的readlink和realpath的替代品,我创建了一些函数,这些函数可以独立于外部命令(如pwd和stuffs)在脚本中运行。

http://www.linuxquestions.org/questions/blog/konsolebox-210384/getting-absolute-paths-of-unix-directories-and-filenames-in-shell-scripts-3956/

其中一个是这个。它会将绝对路径保存到$ __。我使用read来保护路径名扩展。

function getabspath {
    local -a T1 T2
    local -i I=0
    local IFS=/ A

    case "$1" in
    /*)
        read -r -a T1 <<< "$1"
        ;;
    *)
        read -r -a T1 <<< "/$PWD/$1"
        ;;
    esac

    T2=()

    for A in "${T1[@]}"; do
        case "$A" in
        ..)
            [[ I -ne 0 ]] && unset T2\[--I\]
            continue
            ;;
        .|'')
            continue
            ;;
        esac

        T2[I++]=$A
    done

    case "$1" in
    */)
        [[ I -ne 0 ]] && __="/${T2[*]}/" || __=/
        ;;
    *)
        [[ I -ne 0 ]] && __="/${T2[*]}" || __=/.
        ;;
    esac
}

答案 7 :(得分:0)

shell下的一个好解决方案是:

readlink -ev mypathname

打印出已解析点的完整路径名。

答案 8 :(得分:0)

相对路径必须转换为绝对路径,不需要存在!

两个符号链接都不应该解决。

尝试以下单行python解决方案:

abs_path=$(python -c "import os; print(os.path.abspath(\"$rel_path\"))")  

在您的示例中:

python -c "import os; print(os.path.abspath(\"/home/nohsib/dvc/../bop\"))"  

返回/home/nohsib/bop

答案 9 :(得分:-1)

试试这个(假设您的相对路径存储在变量$ rel_path中):

echo "`cd $rel_path; pwd`"