是否有任何此功能的函数?
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
man pwd
: "显示当前工作目录的物理路径(解析所有符号链接)",只需删除 -P
。 - andsens$ brew install coreutils
,接着可以使用 greadlink -f
。 - jgpawletkofunction 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
}
使用pushd
/popd
进入状态以便pwd
有用。
DIRSTACK
的问题,而不是其他什么。很好的解决方案! - cptstubing06sh
兼容性时,pushd; cd <dir>; <cmd>; popd
可以替换为 (cd <dir>; <cmd>)
。 - Abbafei如果您的操作系统支持,可以使用:
realpath -s "./some/dir"
并将其存储在变量中:
some_path="$(realpath -s "./some/dir")"
这会扩展你的路径。在Ubuntu和CentOS上进行了测试,可能在你的系统上不可用。一些人推荐使用readlink,但是readlink的文档中指出:
请注意,realpath(1) 是首选的用于规范化功能的命令。
如果有人想知道为什么要引用变量,那是为了保留路径中的空格。像执行 realpath some path
会得到两个不同的路径结果,但 realpath "some path"
只会返回一个结果。引用参数更胜一筹 :)
感谢 NyanPasu64 提供的信息。如果您不希望其跟随符号链接,则需要添加 -s
。
简单的一行代码:
function abs_path {
(cd "$(dirname '$1')" &>/dev/null && printf "%s/%s" "$PWD" "${1##*/}")
}
使用方法:
function do_something {
local file=$(abs_path $1)
printf "Absolute path to %s: %s\n" "$1" "$file"
}
do_something $HOME/path/to/some\ where
我仍在努力弄清楚如何使其完全忽略路径是否存在的问题(这样它就可以在创建文件时使用)。
cd -
来重置它吗? - devios1realpath -s "./some/dir"
。 - Raid$(cd SOME_DIRECTORY 2> /dev/null && pwd -P)
。这个方法在任何地方都适用。其他解决方案看起来太复杂了。使用readlink -f <相对路径>
命令,例如:
export FULLPATH=`readlink -f ./`
dir_resolve() {
local dir=`dirname "$1"`
local file=`basename "$1"`
pushd "$dir" &>/dev/null || return $? # On error, return error code
echo "`pwd -P`/$file" # output full, link-resolved path with filename
popd &> /dev/null
}
还有另一种方法。您可以在Bash脚本中使用Python嵌入来解析相对路径。
最初的回答abs_path=$(python3 - <<END
from pathlib import Path
path = str(Path("$1").expanduser().resolve())
print(path)
END
)
stat -f "%N" YOUR_PATH
在Linux上,您可能有realpath
可执行文件。如果没有,以下方法可能适用(不仅适用于链接):
readlink -c YOUR_PATH
stat -f“%N”路径
给我返回了与我提供的路径完全相同的路径。 - Lily Ballard自我编辑,我刚注意到OP说他不想要符号链接被解析:
“但是对于我编写的函数,我需要绝对路径,但是它们没有解析其符号链接。”
所以猜想这对他的问题来说并不太合适。 :)
由于多年来我遇到了这种情况很多次,而这一次我需要一个纯bash便携版本,可以在OSX和Linux上使用,因此我去写了一个:
最新版本在此处:
https://github.com/keen99/shell-functions/tree/master/resolve_path
但为了SO的缘故,这是当前版本(我觉得它经过了充分的测试...但我乐意听取反馈!)
也许将其适用于普通的Bourne Shell(sh)并不难,但我没有尝试过...我太喜欢$FUNCNAME了。 :)
#!/bin/bash
resolve_path() {
#I'm bash only, please!
# usage: resolve_path <a file or directory>
# follows symlinks and relative paths, returns a full real path
#
local owd="$PWD"
#echo "$FUNCNAME for $1" >&2
local opath="$1"
local npath=""
local obase=$(basename "$opath")
local odir=$(dirname "$opath")
if [[ -L "$opath" ]]
then
#it's a link.
#file or directory, we want to cd into it's dir
cd $odir
#then extract where the link points.
npath=$(readlink "$obase")
#have to -L BEFORE we -f, because -f includes -L :(
if [[ -L $npath ]]
then
#the link points to another symlink, so go follow that.
resolve_path "$npath"
#and finish out early, we're done.
return $?
#done
elif [[ -f $npath ]]
#the link points to a file.
then
#get the dir for the new file
nbase=$(basename $npath)
npath=$(dirname $npath)
cd "$npath"
ndir=$(pwd -P)
retval=0
#done
elif [[ -d $npath ]]
then
#the link points to a directory.
cd "$npath"
ndir=$(pwd -P)
retval=0
#done
else
echo "$FUNCNAME: ERROR: unknown condition inside link!!" >&2
echo "opath [[ $opath ]]" >&2
echo "npath [[ $npath ]]" >&2
return 1
fi
else
if ! [[ -e "$opath" ]]
then
echo "$FUNCNAME: $opath: No such file or directory" >&2
return 1
#and break early
elif [[ -d "$opath" ]]
then
cd "$opath"
ndir=$(pwd -P)
retval=0
#done
elif [[ -f "$opath" ]]
then
cd $odir
ndir=$(pwd -P)
nbase=$(basename "$opath")
retval=0
#done
else
echo "$FUNCNAME: ERROR: unknown condition outside link!!" >&2
echo "opath [[ $opath ]]" >&2
return 1
fi
fi
#now assemble our output
echo -n "$ndir"
if [[ "x${nbase:=}" != "x" ]]
then
echo "/$nbase"
else
echo
fi
#now return to where we were
cd "$owd"
return $retval
}
这是一个经典的例子,感谢brew:
%% ls -l `which mvn`
lrwxr-xr-x 1 draistrick 502 29 Dec 17 10:50 /usr/local/bin/mvn@ -> ../Cellar/maven/3.2.3/bin/mvn
%% cat test.sh
#!/bin/bash
. resolve_path.inc
echo
echo "relative symlinked path:"
which mvn
echo
echo "and the real path:"
resolve_path `which mvn`
%% test.sh
relative symlinked path:
/usr/local/bin/mvn
and the real path:
/usr/local/Cellar/maven/3.2.3/libexec/bin/mvn
readlink
解析符号链接;但 OP 不希望这样。 - Keith Thompsonecho $(cd some_directory && pwd)
,不解析符号链接,如果some_directory不存在则失败。工作目录不受影响。或者将其赋值给变量MY_PATH=$(cd some_directory && pwd)
。 - qeatzyrealpath -s "./some/dir"
。快速,简单,没有任何函数(如果您的操作系统支持的话,应该会?)就像我的答案所说的那样。 https://dev59.com/Nmw05IYBdhLWcg3wnjPC#64706902 - Raid