bash/fish 命令打印文件的绝对路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3915040/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:44:39  来源:igfitidea点击:

bash/fish command to print absolute path to a file

bashshellpath

提问by dhardy

Question: is there a simple sh/bash/zsh/fish/... command to print the absolute path of whichever file I feed it?

问题:是否有一个简单的 sh/bash/zsh/fish/... 命令来打印我提供给它的任何文件的绝对路径?

Usage case: I'm in directory /a/band I'd like to print the full path to file con the command-line so that I can easily paste it into another program: /a/b/c. Simple, yet a little program to do this could probably save me 5 or so seconds when it comes to handling long paths, which in the end adds up. So it surprises me that I can't find a standard utility to do this — is there really none?

使用情况:我在目录中/a/b,我想打印的完整路径文件c的命令行,这样我可以轻松地将其粘贴到另一个程序:/a/b/c。在处理长路径时,一个简单的小程序可能会为我节省 5 秒左右的时间,最终加起来。所以令我惊讶的是,我找不到一个标准的实用程序来做到这一点——真的没有吗?

Here's a sample implementation, abspath.py:

这是一个示例实现,abspath.py:

#!/usr/bin/python
# Author: Diggory Hardy <[email protected]>
# Licence: public domain
# Purpose: print the absolute path of all input paths

import sys
import os.path
if len(sys.argv)>1:
    for i in range(1,len(sys.argv)):
        print os.path.abspath( sys.argv[i] )
    sys.exit(0)
else:
    print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
    sys.exit(1)

回答by Benjamin Bannier

Try realpath.

试试realpath

$ realpath example.txt
/home/username/example.txt

回答by Paused until further notice.

Try readlinkwhich will resolve symbolic links:

尝试readlink哪个将解析符号链接:

readlink -e /foo/bar/baz

回答by dogbane

#! /bin/sh
echo "$(cd "$(dirname "")"; pwd -P)/$(basename "")"

回答by peterh

Forget about readlinkand realpathwhich may or may not be installed on your system.

忘掉readlinkrealpath可能会或可能不会被你的系统上安装。

Expanding on dogbane's answerabove here it is expressed as a function:

在这里扩展dogbane 的答案,它表示为一个函数:

#!/bin/bash
get_abs_filename() {
  #  : relative filename
  echo "$(cd "$(dirname "")" && pwd)/$(basename "")"
}

you can then use it like this:

然后你可以像这样使用它:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

How and why does it work?

它如何以及为什么起作用?

The solution exploits the fact that the Bash built-in pwdcommand will print the absolute path of the current directory when invoked without arguments.

该解决方案利用了这样一个事实,即pwd当不带参数调用时,Bash 内置命令将打印当前目录的绝对路径。

Why do I like this solution ?

为什么我喜欢这个解决方案?

It is portable and doesn't require neither readlinkor realpathwhich often does not exist on a default install of a given Linux/Unix distro.

它是便携式的,不需要也不readlinkrealpath经常不上的默认安装中存在一个给定的Linux / Unix发行版。

What if dir doesn't exist?

如果 dir 不存在怎么办?

As given above the function will fail and print on stderr if the directory path given does not exist. This may not be what you want. You can expand the function to handle that situation:

如上所述,如果给定的目录路径不存在,该函数将失败并在 stderr 上打印。这可能不是您想要的。您可以扩展函数来处理这种情况:

#!/bin/bash
get_abs_filename() {
  #  : relative filename
  if [ -d "$(dirname "")" ]; then
    echo "$(cd "$(dirname "")" && pwd)/$(basename "")"
  fi
}

Now it will return an empty string if one the parent dirs do not exist.

现在,如果父目录不存在,它将返回一个空字符串。

How do you handle trailing '..' or '.' in input ?

你如何处理尾随的 '..' 或 '.' 在输入中?

Well, it does give an absolute path in that case, but not a minimal one. It will look like:

好吧,在这种情况下它确实提供了绝对路径,但不是最小路径。它看起来像:

/Users/bob/Documents/..

If you want to resolve the '..' you will need to make the script like:

如果你想解决“..”你需要让脚本像:

get_abs_filename() {
  #  : relative filename
  filename=
  parentdir=$(dirname "${filename}")

  if [ -d "${filename}" ]; then
      echo "$(cd "${filename}" && pwd)"
  elif [ -d "${parentdir}" ]; then
    echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
  fi
}

回答by Flimm

$ readlink -m FILE
/path/to/FILE

This is better than readlink -e FILEor realpath, because it works even if the file doesn't exist.

这比readlink -e FILEor 好realpath,因为即使文件不存在它也能工作。

回答by Alexander Klimetschek

This relative path to absolute path converter shell function

这个相对路径到绝对路径转换器shell函数

  • requires no utilities (just cdand pwd)
  • works for directories and files
  • handles ..and .
  • handles spaces in dir or filenames
  • requires that file or directory exists
  • returns nothing if nothing exists at the given path
  • handles absolute paths as input (passes them through essentially)
  • 不需要实用程序(只需cdpwd
  • 适用于目录和文件
  • 把手...
  • 处理目录或文件名中的空格
  • 要求该文件或目录存在
  • 如果给定路径上不存在任何内容,则不返回任何内容
  • 将绝对路径作为输入处理(基本上通过它们)

Code:

代码:

function abspath() {
    # generate absolute path from relative path
    #      : relative filename
    # return : absolute path
    if [ -d "" ]; then
        # dir
        (cd ""; pwd)
    elif [ -f "" ]; then
        # file
        if [[  = /* ]]; then
            echo ""
        elif [[  == */* ]]; then
            echo "$(cd "${1%/*}"; pwd)/${1##*/}"
        else
            echo "$(pwd)/"
        fi
    fi
}

Sample:

样本:

# assume inside /parent/cur
abspath file.txt        => /parent/cur/file.txt
abspath .               => /parent/cur
abspath ..              => /parent
abspath ../dir/file.txt => /parent/dir/file.txt
abspath ../dir/../dir   => /parent/dir          # anything cd can handle
abspath doesnotexist    =>                      # empty result if file/dir does not exist
abspath /file.txt       => /file.txt            # handle absolute path input

Note: This is based on the answers from nolan6000and bsingh, but fixes the file case.

注意:这是基于nolan6000bsingh的答案,但修复了文件案例。

I also understand that the original question was about an existing command line utility. But since this seems to be THE question on stackoverflow for that including shell scripts that want to have minimal dependencies, I put this script solution here, so I can find it later :)

我也明白最初的问题是关于现有的命令行实用程序。但是由于这似乎是 stackoverflow 上的问题,包括希望具有最小依赖性的 shell 脚本,因此我将这个脚本解决方案放在这里,以便稍后找到它:)

回答by lessthanideal

The findcommand may help

find命令可能会有所帮助

find $PWD -name ex*
find $PWD -name example.log

Lists all the files in or below the current directory with names matching the pattern. You can simplify it if you will only get a few results (e.g. directory near bottom of tree containing few files), just

列出当前目录中或当前目录下名称与模式匹配的所有文件。如果您只会得到一些结果(例如,包含少数文件的树底部附近的目录),您可以简化它,只需

find $PWD

I use this on Solaris 10, which doesn't have the other utilities mentioned.

我在 Solaris 10 上使用它,它没有提到其他实用程序。

回答by hluk

If you don't have readlink or realpath utilities than you can use following function which works in bash and zsh (not sure about the rest).

如果您没有 readlink 或 realpath 实用程序,则可以使用以下适用于 bash 和 zsh 的函数(不确定其余部分)。

abspath () { case "" in /*)printf "%s\n" "";; *)printf "%s\n" "$PWD/";; esac; }

This also works for nonexistent files (as does the python function os.path.abspath).

这也适用于不存在的文件(python 函数也是如此os.path.abspath)。

Unfortunately abspath ./../somefiledoesn't get rid of the dots.

不幸的是abspath ./../somefile并没有摆脱这些点。

回答by wjv

Here's a zsh-only function that I like for its compactness. It uses the ‘A' expansion modifier — see zshexpn(1).

这是我喜欢的一个 zsh-only 函数,因为它的紧凑性。它使用“A”扩展修饰符——参见 zshexpn(1)。

realpath() { for f in "$@"; do echo ${f}(:A); done }

回答by babou

There is generally no such thing as theabsolute pathto a file (this statement means that there may be more than one in general, hence the use of the definite article theis not appropriate). An absolute pathis any path that start from the root "/" and designates a file without ambiguity independently of the working directory.(see for example wikipedia).

通常不会有这样的事情absolute path一个文件(这个声明意味着有可能不止一个,一般,因此使用了定冠词是不恰当的)。Anabsolute path是从根“/”开始的任何路径,并独立于工作目录指定一个没有歧义的文件。(参见例如wikipedia)。

A relative pathis a path that is to be interpreted starting from another directory. It may be the working directory if it is a relative pathbeing manipulated by an application (though not necessarily). When it is in a symbolic link in a directory, it is generally intended to be relative to that directory (though the user may have other uses in mind).

Arelative path是要从另一个目录开始解释的路径。如果它是relative path由应用程序操作的,则它可能是工作目录(尽管不一定)。当它位于目录中的符号链接中时,它通常是相对于该目录的(尽管用户可能有其他用途)。

Hence an absolute path is just a path relative to the root directory.

因此绝对路径只是相对于根目录的路径。

A path (absolute or relative) may or may not contain symbolic links. If it does not, it is also somewhat impervious to changes in the linking structure, but this is not necessarily required or even desirable. Some people call canonical path( or canonical file nameor resolved path) an absolute pathin which all symbolic links have been resolved, i.e. have been replaced by a path to whetever they link to. The commands realpathand readlinkboth look for a canonical path, but only realpathhas an option for getting an absolute path without bothering to resolve symbolic links (along with several other options to get various kind of paths, absolute or relative to some directory).

路径(绝对或相对)可能包含也可能不包含符号链接。如果没有,它也有点不受链接结构变化的影响,但这不是必需的,甚至不是可取的。有人叫canonical path(或canonical file nameresolved path)的absolute path其中所有符号链接都得到了解决,即已被替换到whetever它们链接到的路径。这些命令realpathreadlink两者都查找规范路径,但只有realpath一个选项来获取绝对路径,而不必费心解析符号链接(以及其他几个选项来获取各种路径,绝对或相对于某个目录)。

This calls for several remarks:

这需要注意几点:

  1. symbolic links can only be resolved if whatever they are supposed to link to is already created, which is obviously not always the case. The commands realpathand readlinkhave options to account for that.
  2. a directory on a path can later become a symbolic link, which means that the path is no longer canonical. Hence the concept is time (or environment) dependent.
  3. even in the ideal case, when all symbolic links can be resolved, there may still be more than one canonical pathto a file, for two reasons:
    • the partition containing the file may have been mounted simultaneously (ro) on several mount points.
    • there may be hard links to the file, meaning essentially the the file exists in several different directories.
  1. 符号链接只有在它们应该链接到的任何内容已经创建时才能被解析,这显然并非总是如此。命令realpathreadlink选项可以解决这个问题。
  2. 路径上的目录以后可以成为符号链接,这意味着路径不再是canonical. 因此,该概念取决于时间(或环境)。
  3. 即使在理想情况下,当所有符号链接都可以解析时,canonical path一个文件可能仍然不止一个,原因有两个:
    • 包含该文件的分区可能已ro在多个挂载点上同时挂载( )。
    • 可能存在指向该文件的硬链接,这意味着该文件本质上存在于几个不同的目录中。

Hence, even with the much more restrictive definition of canonical path, there may be several canonical paths to a file. This also means that the qualifier canonicalis somewhat inadequate since it usually implies a notion of uniqueness.

因此,即使有更严格的定义canonical path,文件也可能有多个规范路径。这也意味着限定词canonical有点不够用,因为它通常意味着唯一性的概念。

This expands a brief discussion of the topic in an answer to another similar question at Bash: retrieve absolute path given relative

这在Bash 的另一个类似问题的回答中扩展了对该主题的简要讨论:检索给定相对的绝对路径

My conclusion is that realpathis better designed and much more flexible than readlink. The only use of readlinkthat is not covered by realpathis the call without option returning the value of a symbolic link.

我的结论是,realpath它比readlink. 唯一readlink未涵盖的用途是不realpath带选项的调用返回符号链接的值。