Команда realpath не знайдена


24

У мене є Debian стискати amd64. Моя поточна оболонка - баш. Якщо в терміналі я напишу наступне, це працює:

$ uname -a
Linux core 2.6.32-5-amd64 #1 SMP Fri May 10 08:43:19 UTC 2013 x86_64 GNU/Linux
$ echo $SHELL
/bin/bash                                                                                                                                                                                     
$ echo $(realpath test.sh)                                                                                                                                                     
/home/ffortier/test.sh

Мій файл test.sh виглядає так:

#!/bin/bash
echo $(realpath "$1")

Якщо я спробую виконати наступне, я отримаю помилку

$ ./test.sh test.sh 
./test.sh: line 2: realpath: command not found

Як я можу використовувати команду realpath у файлі bash?

Додаткова інформація

$ type -a realpath
realpath is a function                                                                                                                                                                        
realpath ()                                                                                                                                                                                   
{                                                                                                                                                                                             
    f=$@;                                                                                                                                                                                     
    if [ -d "$f" ]; then                                                                                                                                                                      
        base="";                                                                                                                                                                              
        dir="$f";                                                                                                                                                                             
    else                                                                                                                                                                                      
        base="/$(basename "$f")";                                                                                                                                                             
        dir=$(dirname "$f");                                                                                                                                                                  
    fi;                                                                                                                                                                                       
    dir=$(cd "$dir" && /bin/pwd);                                                                                                                                                             
    echo "$dir$base"                                                                                                                                                                          
}           

Відповіді:


9

Чи realpath - це фактична команда чи сценарій? Я би перевірив, щоб побачити, звідки він походить.

$ type -a realpath

Я не знайомий з цим інструментом, і тому він, ймовірно, не є частиною вашого звичайного розповсюдження, можливо, він встановлений у нестандартному місці, якого немає на Bash, $PATHале знаходиться в межах вашого входу $PATH.

У будь-якому випадку вищевказана typeкоманда покаже вам, звідки походить команда, і в цей момент ви можете змінити метод, який ви викликаєте, у своєму сценарії так:

echo $(/path/to/realpath test.sh)

Або внесіть зміни до сценарію, $PATHщоб він також містив це нестандартне місце.

Функції в оболонці

Значна частина вашого оточення не дзвонить, коли ви викликаєте сценарій оболонки. Якщо ви думаєте про це, це має багато сенсу, оскільки ви, як правило, не хочете, щоб у сценаріїв містився весь додатковий багаж, який може мати середовище користувача.

Ви можете або визначити, який вихідний файл надає цю функцію, або джерело її, або просто доручити Bash включити ваше середовище входу.

#!/bin/bash -l
echo $(realpath "$1")

Це функція, див. Редагувати
Франциск

@Francis - так, функції не включаються під час виклику сценарію. Вам потрібно буде їх джерело, якщо ви хочете, щоб вони прийшли разом. Дізнайтеся, який файл надає функцію та джерело її. Якщо ви просто хочете всю свою околицю. потім змінити свій заклик до Баш, #!/bin/bash -l.
slm

Як я можу знайти, звідки ця функція?
Франциск

1
@mikeserv - дякую, коли я написав це, я все ще використовував Fedora 14, який не включав realpath. Моя система Fedora 19 тепер включає цей інструмент. Також зауважте, що ОП використовував ядро ​​Debian w / 2.6, тому його система теж не була б відсутня, realpathвраховуючи його вік.
slm

1
@mikeserv - так, я був здивований, це вже давній Q, але інформація про commandмене все ще корисна. Це більш портативний спосіб робити те, що я показував через оболонки POSIX.
slm

27

Є щонайменше дві програми, які називаються realpath:

  • Стара програма з назад, коли GNU coreutils не включали readlink -f. Зараз це застаріло на користь readlink -f, тому багато розповсюдження перестали його здійснювати.
  • realpathПрограма введена в GNU Coreutils 8.15. Це занадто давно, щоб бути в стислі Debian або навіть хрипкий; на момент написання, Debian нестабільний також не доставляє його . Ця програма дуже близька readlink -f.

Чомусь у вас функція оболонки, яка частково імітує поведінку realpath. Ця емуляція є частковою: якщо ви називаєте її на символічному посиланні, вона не слідкувати за символічним посиланням.

Оскільки це функція оболонки, імовірно завантажена з або через .bashrc, вона доступна лише для коду, що працює у вашій інтерактивній оболонці. Якщо ви хочете, щоб він був доступний для інших програм, якщо припустити, що ви працюєте з Linux, створіть сценарій, що емулює realpath:

#!/bin/sh
readlink -f -- "$@"

(Це не імітує realpathрідко використовувані параметри командного рядка.)


2
Я не можу знайти жодних доказів у coreutils git repo про те, що realpathпрограма вважається устареною Coreutils або що вона не побудована за замовчуванням. Тож Debian повинен її видаляти.
Каз

@Kaz О, ну просто для ускладнення справ, нещодавно coreutils (8.15) представив realpathдвійковий файл, який близький, але не зовсім ідентичний readlink -f. Стайбін Debian несе 8,13. Debian нестабільно вирішив зберегти застарілу програму .
Жил "ТАК - перестань бути злим"

Це не було , що в останній час - це був Jan 2012 savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv

1
@mikeserv Занадто недавнє для розповсюдження у питанні (Дебіан видавлювання). Навіть недавно для поточної стайні Debian.
Жил "ТАК - перестань бути злим"

Це якось страшно. Скільки років їм openssl?
mikeserv

8

Він працює лише в оболонці, оскільки файл скрипта має різну область застосування і не має доступу до ваших локальних функцій та псевдонімів, визначених у ваших rc- файлах. І realpathкоманди фактично не існує у вашій системі.

Отже, або встановіть realpathз пакета, визначте власну функцію (як частину скрипту, перегляньте кілька прикладів ) або вкажіть файл rc у вашому сценарії, де це визначено (наприклад . ~/.bashrc).


Ось етапи встановлення, realpathякщо його немає:

  • Ubuntu: sudo apt-get install coreutils
  • ОС X: brew install coreutils

Ubuntu та Debian

На Debian або Ubuntu, здається, його realpathслід встановити за замовчуванням. Я перевірив останній Debian 8 (Jessie) і, здається, він coreutilsвстановлений за замовчуванням.

Тестовано за допомогою свіжих зображень VM:

$ vagrant init debian/jessie64 && vagrant up --provider virtualbox && vagrant ssh
$ vagrant init ubuntu/vivid64 && vagrant up --provider virtualbox && vagrant ssh

Потім у ВМ:

$ type -a realpath
realpath is /usr/bin/realpath

Замість цього realpathви також можете використовувати readlink -f file(або greadlink), що надається coreutilsпакетом.


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