Як отримати повний шлях до оригінального файлу м'якого символічного посилання?


99

Я хочу scpперенести файл на сервер. Файл є символічним посиланням, і насправді те, що я хочу зробити, це копіювати вихідний файл. У будь-якому випадку я не хочу відстежувати шлях вихідного файлу вручну, тому що його можна замінити. Якщо я можу отримати абсолютний шлях вихідного файлу, я можу sepз ним. Як я можу пройти шлях?


2
Більшість scpверсій за замовчуванням дотримуються посилань, чи не так? Ви повинні перевірити своє і, можливо, заощадити собі якусь роботу.
jw013

@ jw103 Дякую за те, що дав мені знати про це. Я не знав. :)
Еоніл

2
Примітка: scp -rсили, наступні за посиланнями.
Еоніл

Відповіді:


129

Спробуйте цей рядок:

readlink -f `which command`

Якщо він commandзнаходиться у вашій $PATHзмінній, інакше вам потрібно вказати шлях, який ви знаєте.


12
-fповерне шлях до неіснуючої кінцевої цілі, доки існують цілі проміжної ланки ... Використовуйте, -eщоб уникнути цього, тобто. -eповерне нуль, якщо кінцевої цілі не існує.
Пітер.О

10
-fпомилка readlink: illegal option -- fв OSX. Видалення його спрацювало чудово.
Heath Borders

2
@HeathBorders Для OSX, якщо у вас встановлені домашні Coreutils, ви також можете використовувати greadlinkзамість цього.
Адам Гент

23

У Linux readlinkчитає вміст символьної посилання та readlink -fслідкує за посиланнями на посилання на символьні посилання тощо, поки не знайде щось, що не є симпосилання.

Для scp це не потрібно: scp завжди дотримується символьних посилань (він завжди копіює вміст файлу, ігноруючи метадані, за винятком того, що -pзберігає час та режими файлів, коли це можливо).

Якщо ви розчаровані тим, що метадані scp можуть і не можуть зберегти, я пропоную використовувати rsync. Без жодної опції, rsync копіює вміст файлу ігноруючи метадані. Загальновживаний варіант -aзберігає всі метадані різноманітності саду (часи, символічні посилання, дозволи та права власності), і є варіанти збереження екзотичних метаданих, таких як ACL та жорсткі посилання.


readlink виконують лише один крок для посилання зчитування. наприклад, в ubuntu у нас є / bin / zsh, тобто посилання на / etc / alternative / zsh, але це друге символьне посилання. Нарешті ми не отримаємо реальний шлях до файлу чи каталогу. Те саме і з командою stat. Тільки readlink з опцією -f виконує всі рішення.
Znik

9

Я використовую команду ls, stat, readlink.

Візьміть файл /etc/localtimeяк приклад

[flying@lempstacker ~]$ ls /etc/localtime 
/etc/localtime
[flying@lempstacker ~]$ ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 Aug  2 22:41 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

Операція

Використовуючи stat

[flying@lempstacker ~]$ stat /etc/localtime
  File: ‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’
  Size: 35          Blocks: 0          IO Block: 4096   symbolic link
Device: fd01h/64769d    Inode: 272202388   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-11-23 09:00:59.999887800 +0800
Modify: 2016-08-02 22:41:26.090389904 +0800
Change: 2016-08-02 22:41:26.090389904 +0800
 Birth: -
[flying@lempstacker ~]$ stat -c "%N" /etc/localtime
‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’

Використання readlink

[flying@lempstacker ~]$ readlink /etc/localtime
../usr/share/zoneinfo/Asia/Shanghai
[flying@lempstacker ~]$ readlink -f /etc/localtime
/usr/share/zoneinfo/Asia/Shanghai

Здається, що команда readlink -fкраще.

Пояснення

-f, --canonicalize: канонізувати, слідуючи за кожним символьним посиланням у кожному компоненті даної назви рекурсивно; всі, крім останнього компонента, повинні існувати —— Відman readlink


6

Stat надасть вам цю інформацію:

$ stat current
  File: `current' -> `/home/user/releases/build/'
  ...

readlink виконують лише один крок для посилання зчитування. наприклад, в ubuntu у нас є / bin / zsh, тобто посилання на / etc / alternative / zsh, але це друге символьне посилання. Нарешті ми не отримаємо реальний шлях до файлу чи каталогу. Те саме і з командою stat. Тільки readlink з опцією -f виконує всі рішення.
Znik

5

Можна або робити

readlink -f `which command`

або ви можете отримати щось подібне в Linux

stat `which command` | grep File

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

readlink -f "`which command`" 

stat і realink без -f роблять лише один крок. тоді краще зателефонувати до readlink -f.
Znik

3

Я б користувався realpath <symlink>.

Можливо, те, що ви називаєте "джерело", - це "цільовий" файл відповідно до використання ln:Usage: ln [OPTION]... [-T] TARGET LINK_NAME


Спасибі Це спрацювало як шарм! з Mac OSX! де readlinkне вирізали ... дурний мак. lol
JayRizzo

0

readlink -f 'which java' не працювало для мене.

Але це зробило:

readlink -f $(which java)

3
Не працювало, тому що це `не так, 'але $()краще все-таки практикувати.
Стівен Рауч

Чому зворотний голос? Моя відповідь є прийнятною альтернативою і, як йдеться в коментарі, кращою практикою.
NonCreature0714

1
Більшість людей, які відмовилися від голосування, також не коментують, тому просити пояснення щодо голосування за відмову рідко отримаєте вам пояснення, тому що знищений виборець вже пішов і, швидше за все, не повернеться. Я б запропонував вам видалити друкований код, який не працює з вашої відповіді. Я був би готовий проголосувати, якби ви витратили час на його прибирання та пояснили, чому $()краща практика.
Стівен Рауч

Як пояснив вам Стівен, "це не так". Ви повинні інкапсулювати command, але це застаріло. використання $ () краще, тому що інкапсуляція $ ($ (команда)) набагато простіше і не потребує спеціального втечі. Тоді він є кращим. У своєму першому прикладі ви використовували звичайний апостроф, тоді readlink намагається знайти файл з назвою "який java" з пробілом у його імені. Але ви маєте намір - це команда виклику, яка з аргументом java, для знаходження двійкового виконуваного шляху Java.
Znik

0

У MAC OX параметр -f не працює, 'readlink' працює без жодного параметра.

KZs-MacBook-Pro:bin kz$ readlink -f pip3
readlink: illegal option -- f
usage: readlink [-n] [file ...]

KZs-MacBook-Pro:bin kz$ readlink pip3
../../../Library/Frameworks/Python.framework/Versions/3.7/bin/pip3
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.