Bash 如何检索给定相对路径的绝对路径
在给定相对路径的情况下,是否有检索绝对路径的命令 例如,我希望$line包含dirBash 如何检索给定相对路径的绝对路径,bash,shell,path,absolute,Bash,Shell,Path,Absolute,在给定相对路径的情况下,是否有检索绝对路径的命令 例如,我希望$line包含dir/etc/中每个文件的绝对路径 find ./ -type f | while read line; do echo $line done 对于find,最简单的方法可能是只给出它要搜索的绝对路径,例如: find /etc find `pwd`/subdir_of_current_dir/ -type f 使用: 获取所有文件或 echo "$(pwd)/$line" 显示完整路径
/etc/
中每个文件的绝对路径
find ./ -type f | while read line; do
echo $line
done
对于
find
,最简单的方法可能是只给出它要搜索的绝对路径,例如:
find /etc
find `pwd`/subdir_of_current_dir/ -type f
使用:
获取所有文件或
echo "$(pwd)/$line"
显示完整路径(如果相对路径与之相关)他们所说的,除了
find$PWD
或(在bash中)find~+
更方便一些。如果您安装了coreutils包,您通常可以使用readlink-f relative\u file\u name
来检索绝对路径(所有符号链接都已解析)为了它的价值,我投票赞成选出的答案,但想分享一个解决方案。缺点是,它仅限于Linux—在谈到堆栈溢出之前,我花了大约5分钟的时间试图找到OSX的等价物。我相信它就在那里
在Linux上,您可以将readlink-e
与dirname
结合使用
$(dirname $(readlink -e ../../../../etc/passwd))
屈服
/etc/
/etc/passwd
然后使用dirname
的妹妹basename
来获取
文件名
$(basename ../../../../../passwd)
屈服
passwd
把它们放在一起
F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"
屈服
/etc/
/etc/passwd
如果目标目录是安全的,basename
将不返回任何内容
最终的输出结果是双斜杠。试试
realpath
~ $ sudo apt-get install realpath # may already be installed
~ $ realpath .bashrc
/home/username/.bashrc
要避免扩展符号链接,请使用realpath-s
答案来自“realpath可能是最好的 但是 最初的问题一开始就非常混乱,举了一个很糟糕的例子 与上述问题有关 所选答案实际上回答了给出的示例,而不是全部 标题中的问题。第一个命令就是这个答案(是吗 真的吗?我怀疑),没有“/”也能做得很好。我看不见 第二个命令正在做什么 有几个问题是复杂的:
- 将相对路径名更改为绝对路径名
表示,可能什么都没有。
(通常,如果发出命令,如
,则 路径名touch foo/bar
必须为您存在,并且可能在中使用 计算,在实际创建文件之前。)foo/bar
- 可能有多个绝对路径名表示同一文件 (或潜在文件),特别是因为符号链接(符号链接) 在路径上,但可能是由于其他原因(设备可能 安装两次(只读)。一个人可能想也可能不想解决 明确此类符号链接
- 到达非符号链接的符号链接链的末尾 文件或名称。这可能会也可能不会产生绝对路径名, 这取决于它是如何完成的。一个人可能想,也可能不想 将其解析为绝对路径名
readlink foo
without选项仅在其
参数foo
是一个符号链接,这个答案就是它的值
符号链接。没有其他链接。答案可能是相对路径:
符号链接参数的值是多少
但是,readlink
有一些选项(-f-e或-m)适用于所有人
文件,并为其指定一个绝对路径名(不带符号链接的路径名)
实际由参数表示的文件
这对于任何不是符号链接的东西都很好,尽管有人可能会这样做
希望使用绝对路径名而不解析中间路径
路径上的符号链接。这是通过命令realpath-sfoo
对于符号链接参数,readlink
及其选项将
再次解析参数绝对路径上的所有符号链接,但
这还将包括可能遇到的所有符号链接
在参数值之后。如果你想要一份工作,你可能不想要
参数符号链接本身的绝对路径,而不是指向任何对象
它可能链接到。同样,如果foo
是一个符号链接,realpath-sfoo
将
获取绝对路径而不解析符号链接,包括
作为论据给出
没有-s
选项,realpath
与
readlink
,除了简单地读取一个链接的值,还有几个
其他事情。我只是不清楚为什么readlink
有它自己的功能
选项,显然造成了不必要的冗余
realpath
探索网络并不能说明更多,除了可能有
系统之间存在一些差异
结论:realpath
是使用的最佳命令,具有最大的可用性
灵活性,至少适用于此处要求的使用。我认为这是最便携的:
abspath() {
cd "$(dirname "$1")"
printf "%s/%s\n" "$(pwd)" "$(basename "$1")"
cd "$OLDPWD"
}
如果路径不存在,则会失败。如果您在Mac OS X上使用的bash既不存在realpath,也不存在其readlink可以打印绝对路径,您可以选择,但可以编写自己的版本来打印它。 以下是我的实现: (纯bash) (用呆呆的眼神)
与@ernest-a的答案类似,但在不影响
$OLDPWD
或定义新函数的情况下,您可以启动子shell(cd;pwd)
UPD一些解释
“$1”
dirname“$1”
cd“$(dirname“$1”)
进入这个相对目录,并通过运行pwd
shell命令获得它的绝对路径$(basename“$1”)
echo
it如果相对路径是目录路径,请尝试使用我的,应该是最好的:
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath
如果要将包含相对路径的变量转换为绝对路径,可以执行以下操作:
dir=`cd "$dir"`
“cd”回声不带ch
$ abspath I/am/.//..//the/./god/../of///.././war
/Users/leon/I/the/war
$ pwd
/etc/apache2
$ cd ../cups
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath
echo "mydir/doc/ mydir/usoe ./mydir/usm" | awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'
dir=`cd "$dir"`
absolute="$(cd $(dirname \"$file\"); pwd)/$(basename \"$file\")"
#! /bin/sh
# Takes a path argument and returns it as an absolute path.
# No-op if the path is already absolute.
function to-abs-path {
local target="$1"
if [ "$target" == "." ]; then
echo "$(pwd)"
elif [ "$target" == ".." ]; then
echo "$(dirname "$(pwd)")"
else
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
fi
}
line=$(echo ${line/#..\//`cd ..; pwd`\/})
line=$(echo ${line/#.\//`pwd`\/})
echo $line
to_abs_path() {
python -c "import os; print os.path.abspath('$1')"
}
to_abs_path "/some_path/../secrets"
function getRealPath()
{
local -i traversals=0
currentDir="$1"
basename=''
while :; do
[[ "$currentDir" == '.' ]] && { echo "$1"; return 1; }
[[ $traversals -eq 0 ]] && pwd=$(cd "$currentDir" 2>&1 && pwd) && { echo "$pwd/$basename"; return 0; }
currentBasename="$(basename "$currentDir")"
currentDir="$(dirname "$currentDir")"
[[ "$currentBasename" == '..' ]] && (( ++traversals )) || { [[ traversals -gt 0 ]] && (( traversals-- )) || basename="$currentBasename/$basename"; }
done
}
absPathDirname()
{
[ -d "${1}" ] && set -- "${1}" || set -- "`dirname "${1}"`" "/`basename "${1}"`"
echo "`cd "${1}"; pwd`${2}";
}
absPathMinusD()
{
[ -d "${1}" ] && set -- "${1}" || set -- "${1%${1##*/}}" "/${1##*/}"
echo "`cd "${1:-.}"; pwd`${2}";
}
absPathGrep()
{
echo "`[ "${1##/*}" ] && echo "$1" | grep -Eo '^(.*/)?\.\.($|/)' | { read d && cd "$d"; echo "${PWD}/${1#$d}"; } || echo "$1"`"
}
absPathShellReplace()
{
E="${1##*/}"; D="${E#$E${E#.}}"; DD="${D#$D${D#..}}"
DIR="${1%$E}${E#$DD}"; FILE="${1#$DIR}"; SEP=${FILE:+/}
echo "`cd "${DIR:-.}"; pwd`${SEP#$DIR}$FILE"
}