在bash中扩展可能的相对路径

laa*_*aar 68 bash absolute-path

作为我的脚本的参数,有一些文件路径.那些当然可以是相对的(或包含〜).但是对于我编写的函数,我需要绝对的路径,但是没有解析它们的符号链接.

这有什么功能吗?

Ami*_*ani 64

MY_PATH=$(readlink -f $YOUR_ARG)将解决像"./"和的相对路径"../"

考虑这一点(来源):

#!/bin/bash
dir_resolve()
{
cd "$1" 2>/dev/null || return $?  # cd to desired directory; if fail, quell any error messages but return exit status
echo "`pwd -P`" # output full, link-resolved path
}

# sample usage
if abs_path="`dir_resolve \"$1\"`"
then
echo "$1 resolves to $abs_path"
echo pwd: `pwd` # function forks subshell, so working directory outside function is not affected
else
echo "Could not reach $1"
fi
Run Code Online (Sandbox Code Playgroud)

  • 遗憾的是,OS X上的readlink不支持-f. (12认同)
  • 要在OS X上获得`readlink -f`功能,你可以使用[Homebrew](http://brew.sh/)然后运行:`$ brew install coreutils`然后你可以使用`greadlink -f`. (6认同)

Mik*_*uel 41

http://www.linuxquestions.org/questions/programming-9/bash-script-return-full-path-and-filename-680368/page3.html有以下内容

function abspath {
    if [[ -d "$1" ]]
    then
        pushd "$1" >/dev/null
        pwd
        popd >/dev/null
    elif [[ -e $1 ]]
    then
        pushd "$(dirname "$1")" >/dev/null
        echo "$(pwd)/$(basename "$1")"
        popd >/dev/null
    else
        echo "$1" does not exist! >&2
        return 127
    fi
}
Run Code Online (Sandbox Code Playgroud)

它使用pushd/ popd进入一个pwd有用的状态.

  • 当瞄准标准的`sh`兼容性时,`pushd; cd <dir>; <CMD>; popd`可以替换为`(cd <dir>; <cmd>)`. (4认同)
  • 可悲的是,这真的是这里最好的答案,它没有投票给它所属的地方。+1 用于准确回答 OP 的问题。他想要不解决符号链接,这实际上是 bash 的本地“DIRSTACK”的问题,没有别的问题。不错的解决方案! (2认同)

Rai*_*aid 20

如果您的操作系统支持,请使用:

realpath -s "./some/dir"
Run Code Online (Sandbox Code Playgroud)

并在变量中使用它:

some_path="$(realpath -s "./some/dir")"
Run Code Online (Sandbox Code Playgroud)

这将扩展你的道路。在 Ubuntu 和 CentOS 上进行了测试,可能不适用于您的系统。有些人推荐 readlink,但 readlink 的文档说:

注意 realpath(1) 是用于规范化功能的首选命令。

如果人们想知道我为什么引用变量,这是为了保留路径中的空格。就像这样做realpath some path会给你两种不同的路径结果。但realpath "some path"会返还一张。引用参数 ftw :)

感谢 NyanPasu64 的提醒。-s如果您不希望它遵循符号链接,则需要添加。


and*_*ens 16

简单的单线程:

function abs_path {
  (cd "$(dirname '$1')" &>/dev/null && printf "%s/%s" "$PWD" "${1##*/}")
}
Run Code Online (Sandbox Code Playgroud)

用法:

function do_something {
    local file=$(abs_path $1)
    printf "Absolute path to %s: %s\n" "$1" "$file"
}
do_something $HOME/path/to/some\ where
Run Code Online (Sandbox Code Playgroud)

我仍在试图弄清楚如何让它完全忘记路径是否存在(所以它也可以在创建文件时使用).

  • 没必要.注意parens,它们导致里面的命令在子shell中运行.子shell的状态(例如工作目录)不会泄漏到其父shell.在这里阅读更多内容:http://tldp.org/LDP/abs/html/subshel​​ls.html (4认同)

小智 8

这对我来说是OS X的诀窍: $(cd SOME_DIRECTORY 2> /dev/null && pwd -P)

它应该适用于任何地方 其他解决方案似乎太复杂了.


Vit*_*ner 5

在OS X上你可以使用

stat -f "%N" YOUR_PATH
Run Code Online (Sandbox Code Playgroud)

在linux上你可能有realpath可执行文件.如果没有,以下可能会起作用(不仅仅是链接):

readlink -c YOUR_PATH
Run Code Online (Sandbox Code Playgroud)

  • OS X答案不起作用.`stat -f"%N"PATH`给了我完全相同的路径. (18认同)
  • 在Linux上(使用coreutils 8.20)它是`readlink -f YOUR_PATH` (7认同)

isa*_*pir 5

使用readlink -f <relative-path>,例如

export FULLPATH=`readlink -f ./`
Run Code Online (Sandbox Code Playgroud)