Як я можу отримати абсолютне ім'я файлу в скрипті оболонки на Mac OS X?


19

Я хотів би отримати абсолютне ім'я файлу сценарію, який зараз виконується. Посилання також мають бути вирішені.

У Linux це, здається, робиться так:

$(readlink -mn "$0")

але, readlinkздається, працює зовсім по- іншому на Mac OS X.

Я читав, що це робиться за допомогою

$(realpath $0)

в BSD, але це також не працює. Mac OS X не має realpath.

Будь-яка ідея?


1
Подивіться це питання на SO: stackoverflow.com/questions/799679/…
Telemachus


Відповіді:


19

Я обманюю і використовую perl для цієї речі:

#!/bin/bash
dirname=`perl -e 'use Cwd "abs_path";print abs_path(shift)' $0`
echo $dirname

Ви б могли подумати, що я просто напишу весь сценарій в perl, і часто це роблю, але не завжди.


Це працює, велике спасибі Я дам вам підсумок, як тільки зможу. Хтось має "чисту оболонку", як це зробити?
Хусі

1
Боюся, що це так добре, як виходить. (Враховуючи безліч хакерських "чистих оболонок", які можна знайти в Google.)
Arjan

інша можливість (хоча і потворна) полягає в тому, щоб пройти шлях "..", запам'ятовуючи (через рекурсію або масив), поки ".." не поверне той самий файл, який ви раніше мали (тобто: ви вгорі), а потім поверніться до складання шлях, як ви йдете. Я бачив, що резервне програмне забезпечення Legato's Networker робило це під час страйсу як метод отримання «справжнього» шляху (але, можливо, не абсолютного). Але це було б набагато більше коду, ніж вище.
ericslaw

Не впевнений, чому хтось змінив код, щоб використовувати $ 1 замість $ 0. Хіба не $ 1 - перший аргумент до скрипту bash? Я хотів шлях до виконання скрипта bash, але це не перший аргумент.
ericslaw

27
#!/usr/bin/env bash
scriptDir="$(cd "$(dirname "$0")" && pwd -P)"

Працює і в MacOSX.
Алексар

1
Це супер! Є багато інших надскладних відповідей, що плавають навколо.
Jason S

3
Це працює лише для файлів у зв'язаній папці, а не для файлів із посиланням взагалі
Герхард Бургер,

1
Це також корисно до unset -v CDPATHCD, оскільки CD може спричинити небажаний вихід, якщо встановлено CDPATH.
Бінарний Філі

Щоб мати справу з принаймні одним шаром символу посилання на файл, ви також можете перевірити сумісний спосіб з readlink (у маків немає -f): scriptDir=$(unset -v CDPATH; cd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE)")" && pwd -P)
Бінарний Філі

0

Це обробляє комбінації символьних посилань, і він працює над файлами та папками:

#!/usr/bin/env bash
realpath()
{
    if ! pushd $1 &> /dev/null; then 
        pushd ${1##*/} &> /dev/null
        echo $( pwd -P )/${1%/*}
    else
        pwd -P
    fi
    popd > /dev/null
}

Але він не підтримує реальний шлях - відносний до. Для цього потрібно перетворення, описане тут .


0

Інший підхід:

# Install.
brew install coreutils

# Use the GNU variant.
grealpath --help
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.