Як отримати повний шлях до файлу в bash?


23

Я хотів би простий спосіб отримати повний шлях до файлу. Я зараз набираю це:

echo `pwd`/file.ext

Намагаючись скоротити його, я склав псевдонім баш:

alias fp='echo `pwd`/'

Але тепер, якщо я набираю fp file.ext, з’являється пробіл між /і file.ext.

Чи така команда вже існує, і я її пропускаю? Якщо ні, то як би я пішов про створення такого псевдоніма або функції в bash?

Відповіді:


31

Для систем Linux вам слід встановити readlinkпроект GNU coreutils і це зробити:

readlink -f file.ext

У системах Debian / ubuntu може бути встановлена ​​утиліта realpath, яка "забезпечує в основному той же функціонал, що і /bin/readlink -fв пакеті coreutils".


readlink -f(або realpath, що є старшою утилітою, яка зберігається для сумісності) додатково розширить усі символічні посилання, що не обов’язково бажано.
Жил "ТАК - перестань бути злим"

8
fyi: не працює на macosx.
акіра

На моєму комп'ютері я встановив 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"
Жил "ТАК - перестань бути злим"

@Gilles: за яких обставин?
акіра

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

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

bash - це "поганий" тут, як здається, bash дає те, про що ти хочеш.
акіра

3

Ви можете використовувати:

realpath file.ext

У мене цього немає. Звідки це походить?
frabjous

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

Я використовую Arch. Це не на основі Debian, але пакет AUR все одно є. Не впевнений, що варто встановити, якщо у мене вже є посилання для читання.
frabjous

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

@frabjous: Ви не вказали , яку систему ви перебуваєте, але якщо він використовує Схильність на основі менеджера пакетів (Debian, Ubuntu, Mint і т.д.), ви можете ввести , apt-cache search realpathщоб показати , що Coreutils і простий ПР » 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.