Как получить полный путь к файлу в bash?


22

Я хотел бы получить простой способ получить полный путь к файлу. Я сейчас набираю это:

echo `pwd`/file.ext

Пытаясь сократить его, я сделал псевдоним bash:

alias fp='echo `pwd`/'

Но теперь , если я печатаю fp file.ext, есть пространство , которое появляется между /и file.ext.

Такая команда уже существует, и мне ее не хватает? Если нет, то как мне создать псевдоним или функцию в bash?

Ответы:


30

В системах Linux у вас должен быть readlinkустановлен проект GNU coreutils, и вы можете сделать это:

readlink -f file.ext

В системах Debian / Ubuntu может быть установлена утилита realpath, которая «предоставляет в основном те же функции, что и /bin/readlink -fв пакете coreutils».


readlink -f(или realpath, которая является более старой утилитой, сохраняемой для совместимости) дополнительно расширит все символические ссылки, что не обязательно желательно.
— Жиль "ТАК - перестать быть злым"

8
К вашему сведению: не работает на Macosx.
— Акира

На моем Mac я установил coreutils, используя homebrew, и он включает realpath.
— Даг Харрис

7

Вместо pwdкоманды используйте PWDпеременную (она также в POSIX):

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

Если вам нужна поддержка Windows, распознавание абсолютных путей будет более сложным, поскольку у каждого порта инструментов Unix есть свои правила для преобразования путей к файлам. С Cygwin используйте cygpathутилиту.


Может быть, это ваш выбор, но эта функция не выведет новую строку.
— cYrus

этот подход имеет преимущество использования только встроенных командных оболочек, что быстрее, чем вызов внешних двоичных файлов. Вы должны сделать этот факт немного более ясным.
— Акира

4

чтобы ответить на ваш вопрос с тем, что вы используете прямо сейчас:

псевдоним расширяется в той позиции, где вы печатаете прямо сейчас. Вы ввели:

% fp<SPACE>file.ext

это становится

% echo `pwd`<SPACE>file.exe

Вы можете использовать функцию, чтобы избежать этого:

function fp() {
    echo `pwd`/"$1"
}

Вы можете использовать это как обычно:

% fp file.ext

Вам нужны двойные кавычки вокруг переменных и подстановок команд:echo "`pwd`/$1"
— Жиль "ТАК, перестань быть злым"

@ Жиль: при каких обстоятельствах?
— Акира

2
@akira: Всегда используйте двойные кавычки, если только вы не хотите, чтобы результат раскрытия рассматривался как шаблон глобинга, а результаты глобализации разбивать на слова. Здесь вы создаете одно имя файла, поэтому нужны двойные кавычки (попробуйте свою функцию с файлом, который называется *в каталоге, содержащем другие файлы).
— Жиль "ТАК - перестань быть злым"

' ' скрывается оболочкой (в моем случае это zsh) и расширяется до того, как они попадают в функцию. fp *дает, /tmp/4cc3ea0c1b34bтак как это первый параметр для функции. другие параметры будут другими файлами в каталоге. как только у меня есть файл с именем ' ', функция все еще работает, как и ожидалось, вызывая его с помощью «*» или * или *
— akira

Bash, как кажется, «плохой», bash дает то, к чему вы обращаетесь.
— Акира

3

Ты можешь использовать:

realpath file.ext

У меня этого нет. Откуда это?
— безумно

@frabjous: он специфичен для Debian и его производных и будет установлен, только если вы запросили его или пакет, который от него зависит.
— Жиль "ТАК - перестать быть злым"

Я использую Arch. Он не основан на Debian, но в AUR есть пакет для него. Не уверен, что стоит установить, если у меня уже есть ссылка для чтения.
— торжественно

Ну, это вариант; или вы можете рассмотреть функцию, см. ответ Жиля . Во всяком случае, это зависит от реального использования, которое вы хотите сделать с этим (мне любопытно).
— cyrus

@frabjous: вы не указали, в какой системе вы находитесь, но если он использует менеджер пакетов на основе Aptitude (Debian, Ubuntu, Mint и т. д.), вы можете напечатать, apt-cache search realpathчтобы показать, что пакеты coreutils и plain ol ' realpath оба содержат это. Затем вы можете напечатать sudo apt-get install realpath(или coreutils), чтобы установить его.
— Майкл Шепер

1

С /programming//a/3915420/5795941

Это единственный способ, который приемлем для меня. Не расширяет ссылки, такие как realpath и readlink, и это классический способ сделать это, который я видел повсюду.

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.