Симлінк-псевдонім файлів у підкаталогах без зміни поточного каталогу


11

Схоже, має бути простим посилання одного файлу на новий файл у підкаталозі .... .... без переміщення підкаталогів. Але щось про синтаксис викликає здивування і суперечить тому, що я б очікував. Ось тестовий випадок:

mkdir temp
cd temp
mkdir deploy
echo "Contents of the build file!" > deploy/resources.build.php
ln -s deploy/resources.build.php deploy/resources.php
cat deploy/resources.php #bad symlink

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

ln -s deploy/resources.build.php resources.php
cat deploy/resources.php

Також не працює, оскільки створює символьне посилання в темп-каталозі замість підкаталогу розгортання.

cd deploy
ln -s resources.build.php resources.php
cd ..

Це працює, але я вважаю за краще знати, як це зробити, не змінюючи каталогів.

Використання повного шляху, наприклад:

/home/whatever/src/project/temp/stuff/temp/deploy/resources.build.php

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

Як я можу створити симпосилання між двома файлами у підкаталозі, не переходячи до цього підкаталогу та виходячи з нього та надаючи новому файлу "псевдонім" нове ім'я?

Відповіді:


10

Але щось про синтаксис викликає здивування і суперечить тому, що я б очікував.

Аргументами для lnтакої форми, яку ви використовуєте, є:

ln [ОПЦІЯ] ... [-T] ЦІЛЬНА LINK_NAME (1-а форма)

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

$ echo foo >foo
$ ln -s foo bar1
$ ln -s $PWD/foo bar2
$ cat bar1
foo
$ cat bar2
foo
$ ls -l bar1 bar2
lrwxrwxrwx 1 matt matt  3 Dec 29 16:29 bar1 -> foo
lrwxrwxrwx 1 matt matt 29 Dec 29 16:29 bar2 -> /home/matt/testdir/foo

У цьому прикладі я створюю 2 посилання, названі "bar1" і "bar2", які вказують на той самий файл. lsпоказує, що самі посилання мають різний зміст, хоча - один містить абсолютний шлях, а один - відносний шлях. Через це один продовжував би працювати, навіть якщо його було перенесено в інший каталог, а інший не буде:

$ mv bar2 /tmp
$ cat /tmp/bar2
foo
$ mv bar1 /tmp
$ cat /tmp/bar1
cat: /tmp/bar1: No such file or directory

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

Якщо ви хочете створити файл з назвою розгорнути / ресурси.php, який посилається на розгортання / resource.build.php, вам потрібно вирішити, чи потрібно створити абсолютне посилання (яке стійке до переміщення символьної посилання, але розривається, якщо ціль переміщена) або відносне символьне посилання (яке буде тримати роботу до тих пір, поки і симпосилання, і ціль будуть переміщені разом і підтримувати однакові відносні шляхи).

Щоб створити абсолютне посилання, ви можете:

$ ln -s $PWD/deploy/resources.build.php deploy/resources.php

Щоб створити відносну, спершу слід визначити відносний шлях від джерела до цілі. У цьому випадку, оскільки джерело та ціль знаходяться в одному каталозі відносно один одного, ви можете просто зробити:

$ ln -s resources.build.php deploy/resources.php

Якщо вони не були в одному каталозі, вам потрібно буде зробити щось на кшталт:

$ ln -s ../foo/f bar/b

У цьому випадку, хоча вони fooі barобидва знаходяться у вашому поточному каталозі, вам потрібно включити ../в ln ціль, оскільки вона описує, як знайти fз каталогу, що містить b.

Це надзвичайно тривале пояснення, але, сподіваємось, це допоможе вам зрозуміти lnсинтаксис трохи краще.


3

Ви можете створити посилання в передплаті, як описано нижче:

  (cd deploy && ln -s resources.build.php resources.php && cat resources.php)

Коли допоміжна частина закінчиться виконанням, ви опинитесь у правильному каталозі.

Можна також спробувати

 ln -s resources.build.php deploy/resources.php

яка також працює, нехтуючи включенням в CL той факт, що файл resource.build.php знаходиться не в каталозі, де ви видаєте команду, а насправді знаходиться всередині ./deploy .


Це чорна магія, сер!
Kzqai

1

Це збентежило мене, поки я не зрозумів, що симпосилання - це в основному конфігураційний файл. тобто як я записав би дані про шлях у простий текстовий файл:

ln -s [target] [link name]

стає:

echo [target] > [link name]

Помилка , що я (і , ймовірно , OP) робив це в міркуванні ¯Ln потреби знати про фото його орієнтації. Інн не хвилює. Це просто запис деякої інформації про шлях у файл. Це цілком розумна команда ln :

ln -s /path/doesnt/exist/file.err
ll
file.err -> /path/doesnt/exist/file.err

Звідси:

ln -s deploy/resources.build.php deploy/resources.php

створює файл simlink, викликаний resources.phpу ./deployпапці, на яку посилається файл resources.build.phpу папці ./deploy/deploy/.

Це навряд чи те, що ви хочете, і дає поганий (розірваний) зв’язок. З посиланням немає нічого поганого, якщо ви помістите цей файл туди, то посилання працює. Однак (як вказували інші), чого я і ОП хотіли:

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