bash 如何检索给定相对的绝对路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4175264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to retrieve absolute path given relative
提问by nubme
Is there a command to retrieve the absolute path given the relative path?
是否有命令可以检索给定相对路径的绝对路径?
For example I want $line to contain the absolute path of each file in dir ./etc/
例如我希望 $line 包含目录中每个文件的绝对路径 ./etc/
find ./ -type f | while read line; do
echo $line
done
采纳答案by mpapis
use:
用:
find $(pwd)/ -type f
to get all files or
获取所有文件或
echo $(pwd)/$line
to display full path (if relative path matters to)
显示完整路径(如果相对路径很重要)
回答by epere4
Try realpath
.
试试realpath
。
~ $ sudo apt-get install realpath # may already be installed
~ $ realpath .bashrc
/home/username/.bashrc
To avoid expanding symlinks, use realpath -s
.
为避免扩展符号链接,请使用realpath -s
.
The answer comes from "bash/fish command to print absolute path to a file".
答案来自“用于打印文件绝对路径的 bash/fish 命令”。
回答by Moritz Bunkus
If you have the coreutils package installed you can generally use readlink -f relative_file_name
in order to retrieve the absolute one (with all symlinks resolved)
如果您安装了 coreutils 软件包,您通常可以使用readlink -f relative_file_name
它来检索绝对软件包(已解析所有符号链接)
回答by Eugen Konkov
#! /bin/sh
echo "$(cd "$(dirname "")"; pwd)/$(basename "")"
UPDSome explanations
UPD一些解释
- This script get relative path as argument
"$1"
- Then we get dirnamepart of that path (you can pass either dir or file to this script):
dirname "$1"
- Then we
cd "$(dirname "$1")
into this relative dir and get absolute path for it by runningpwd
shell command - After that we append basenameto absolute path:
$(basename "$1")
- As final step we
echo
it
- 此脚本获取相对路径作为参数
"$1"
- 然后我们获得该路径的dirname部分(您可以将 dir 或 file 传递给该脚本):
dirname "$1"
- 然后我们
cd "$(dirname "$1")
进入这个相对目录并通过运行pwd
shell 命令获取它的绝对路径 - 之后,我们将basename附加到绝对路径:
$(basename "$1")
- 作为最后一步,我们
echo
就
回答by synthesizerpatel
For what it's worth, I voted for the answer that was picked, but wanted to share a solution. The downside is, it's Linux only - I spent about 5 minutes trying to find the OSX equivalent before coming to Stack overflow. I'm sure it's out there though.
对于它的价值,我投票支持选择的答案,但想分享一个解决方案。缺点是,它仅适用于 Linux - 在堆栈溢出之前,我花了大约 5 分钟试图找到 OSX 等效项。不过我确定它就在那里。
On Linux you can use readlink -e
in tandem with dirname
.
在 Linux 上,您可以readlink -e
与dirname
.
$(dirname $(readlink -e ../../../../etc/passwd))
yields
产量
/etc/
And then you use dirname
's sister, basename
to just get
the filename
然后你使用dirname
's'sister,basename
来获取文件名
$(basename ../../../../../passwd)
yields
产量
passwd
Put it all together..
全部放在一起..
F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"
yields
产量
/etc/passwd
You're safe if you're targeting a directory, basename
will return nothing
and you'll just end up with double slashes in the final output.
如果您的目标是目录,那么您是安全的,basename
不会返回任何内容,并且最终输出中只会出现双斜杠。
回答by Ernest A
I think this is the most portable:
我认为这是最便携的:
abspath() {
cd "$(dirname "")"
printf "%s/%s\n" "$(pwd)" "$(basename "")"
cd "$OLDPWD"
}
It will fail if the path does not exist though.
如果路径不存在,它将失败。
回答by babou
realpath
is probably best
realpath
可能是最好的
But ...
但 ...
The initial question was very confused to start with, with an example poorly related to the question as stated.
最初的问题一开始就很困惑,有一个与所述问题关系不大的例子。
The selected answer actually answers the example given, and not at all the question in the title. The first command is that answer (is it really ? I doubt), and could do as well without the '/'. And I fail to see what the second command is doing.
所选答案实际上回答了给出的示例,而不是标题中的问题。第一个命令就是那个答案(真的吗?我怀疑),并且没有“/”也可以。而且我看不到第二个命令在做什么。
Several issues are mixed :
几个问题是混合的:
changing a relative pathname into an absolute one, whatever it denotes, possibly nothing. (Typically, if you issue a command such as
touch foo/bar
, the pathnamefoo/bar
must exist for you, and possibly be used in computation, before the file is actually created.)there may be several absolute pathname that denote the same file (or potential file), notably because of symbolic links (symlinks) on the path, but possibly for other reasons (a device may be mounted twice as read-only). One may or may not want to resolve explicity such symlinks.
getting to the end of a chain of symbolic links to a non-symlink file or name. This may or may not yield an absolute path name, depending on how it is done. And one may, or may not want to resolve it into an absolute pathname.
将相对路径名更改为绝对路径名,无论它表示什么,可能什么都没有。(通常,如果您发出诸如 之类的命令
touch foo/bar
,则foo/bar
在实际创建文件之前,路径名必须存在,并且可能用于计算。)可能有多个绝对路径名表示同一个文件(或潜在文件),主要是因为路径上的符号链接(符号链接),但也可能是其他原因(设备可能以只读方式挂载两次)。人们可能希望也可能不想明确解析此类符号链接。
到达非符号链接文件或名称的符号链接链的末尾。这可能会也可能不会产生绝对路径名,具体取决于它是如何完成的。人们可能希望也可能不想将其解析为绝对路径名。
The command readlink foo
without option gives an answer only if its
argument foo
is a symbolic link, and that answer is the value of that
symlink. No other link is followed. The answer may be a relative path:
whatever was the value of the symlink argument.
readlink foo
不带选项的命令仅在其参数foo
是符号链接时才给出答案,并且该答案是该符号链接的值。没有遵循其他链接。答案可能是一个相对路径:无论符号链接参数的值是什么。
However, readlink
has options (-f -e or -m) that will work for all
files, and give one absolute pathname (the one with no symlinks) to
the file actually denoted by the argument.
但是,readlink
具有适用于所有文件的选项(-f -e 或 -m),并为参数实际表示的文件提供一个绝对路径名(没有符号链接的路径名)。
This works fine for anything that is not a symlink, though one might
desire to use an absolute pathname without resolving the intermediate
symlinks on the path. This is done by the command realpath -s foo
这适用于任何不是符号链接的内容,尽管人们可能希望使用绝对路径名而不解析路径上的中间符号链接。这是由命令完成的realpath -s foo
In the case of a symlink argument, readlink
with its options will
again resolve all symlinks on the absolute path to the argument, but
that will also include all symlinks that may be encountered by
following the argument value. You may not want that if you desired an
absolute path to the argument symlink itself, rather than to whatever
it may link to. Again, if foo
is a symlink, realpath -s foo
will
get an absolute path without resolving symlinks, including the one
given as argument.
在符号链接参数的情况下,readlink
其选项将再次解析参数绝对路径上的所有符号链接,但这也将包括跟随参数值可能遇到的所有符号链接。如果您想要参数符号链接本身的绝对路径,而不是它可能链接到的任何内容,则您可能不希望这样做。同样,如果foo
是一个符号链接,realpath -s foo
将获得一个不解析符号链接的绝对路径,包括作为参数给出的那个。
Without the -s
option, realpath
does pretty much the same as
readlink
, except for simply reading the value of a link, as well as several
other things. It is just not clear to me why readlink
has its
options, creating apparently an undesirable redundancy with
realpath
.
如果没有这个-s
选项,除了简单地读取链接的值以及其他一些事情之外,realpath
它的作用与 几乎相同
readlink
。我不清楚为什么readlink
有它的选择,显然会产生不受欢迎的冗余
realpath
。
Exploring the web does not say much more, except that there may be some variations across systems.
探索网络并没有说更多,只是不同系统之间可能存在一些差异。
Conclusion : realpath
is the best command to use, with the most
flexibility, at least for the use requested here.
结论 :realpath
是最好的命令,具有最大的灵活性,至少对于此处要求的使用而言。
回答by hashchange
My favourite solution was the oneby @EugenKonkov because it didn't imply the presence of other utilities (the coreutils package).
我最喜欢的解决方案是一个由@EugenKonkov,因为它并不意味着其他公用事业存在(的coreutils软件包)。
But it failed for the relative paths "." and "..", so here is a slightly improved version handling these special cases.
但是相对路径“.”失败了。和“..”,所以这里有一个处理这些特殊情况的稍微改进的版本。
It still fails if the user doesn't have the permission to cd
into the parent directory of the relative path, though.
但是,如果用户没有cd
进入相对路径的父目录的权限,它仍然会失败。
#! /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=""
if [ "$target" == "." ]; then
echo "$(pwd)"
elif [ "$target" == ".." ]; then
echo "$(dirname "$(pwd)")"
else
echo "$(cd "$(dirname "")"; pwd)/$(basename "")"
fi
}
回答by biomiker
Eugen's answer didn't quite work for me but this did:
欧根的回答对我来说不太适用,但这确实适用:
absolute="$(cd $(dirname \"$file\"); pwd)/$(basename \"$file\")"
Side note, your current working directory is unaffected.
旁注,您当前的工作目录不受影响。
回答by MrSegFaulty
The best solution, imho, is the one posted here: https://stackoverflow.com/a/3373298/9724628.
最好的解决方案,恕我直言,是在这里发布的:https: //stackoverflow.com/a/3373298/9724628。
It does require python to work, but it seems to cover all or most of the edge cases and be very portable solution.
它确实需要 python 才能工作,但它似乎涵盖了所有或大部分的边缘情况,并且是非常便携的解决方案。
- With resolving symlinks:
- 通过解析符号链接:
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" path/to/file
- or without it:
- 或没有它:
python -c "import os,sys; print(os.path.abspath(sys.argv[1]))" path/to/file