Symlink aliasing file dalam subdirektori tanpa mengubah direktori saat ini

11

Sepertinya mudah untuk menyinkronkan satu file ke file baru di subdirektori .... .... tanpa memindahkan subdirektori. Tetapi sesuatu tentang sintaks membingungkan dan bertentangan dengan apa yang saya harapkan. Berikut ini adalah test case:

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

Ini hanya membuat symlink yang rusak! Saya menjalankan ini dalam skrip penyiapan lingkungan build, jadi saya ingin menghindari mengubah direktori kerja saat ini jika memungkinkan.

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

Juga tidak berfungsi karena itu menciptakan symlink di direktori temp daripada subdirektori deploy.

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

Ini berfungsi, tetapi saya lebih suka tahu bagaimana melakukannya tanpa mengubah direktori.

Menggunakan jalur lengkap seperti:

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

Bekerja, tetapi tidak berat dan agak tidak praktis, terutama di lingkungan build di mana semua hal proyek mungkin berbeda antara build, dan sejenisnya.

Bagaimana saya bisa membuat symlink antara dua file dalam subdirektori, tanpa berpindah ke subdirektori itu dan keluar darinya, dan sambil memberikan file baru "alias" nama baru?

Kzqai
sumber

Jawaban:

10

Tetapi sesuatu tentang sintaks membingungkan dan bertentangan dengan apa yang saya harapkan.

Argumen untuk ln, dalam bentuk yang Anda gunakan, adalah:

Di [OPTION] ... [-T] TARGET LINK_NAME (formulir 1)

Yang membingungkan, tidak intuitif adalah bahwa ketika Anda membuat symlink, argumen target untuk lntidak diharapkan menjadi path ke file, tetapi isi dari symlink yang akan dibuat. Jika Anda memikirkannya sejenak, jelas itu harus seperti itu. Mempertimbangkan:

$ 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

Dalam contoh itu saya membuat 2 symlink, bernama "bar1" dan "bar2", yang menunjuk ke file yang sama. lsmenunjukkan bahwa symlink itu sendiri memiliki konten yang berbeda, - satu berisi path absolut, dan satu berisi path relatif. Karena itu, yang satu akan terus bekerja walaupun dipindahkan ke direktori lain, dan yang lain tidak akan:

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

Jadi, mengingat bahwa kita harus dapat membuat kedua symlink relatif dan absolut, dan bahkan untuk membuat symlink yang rusak yang akan menjadi tidak rusak jika file target nanti dibuat, argumen target harus ditafsirkan sebagai teks bentuk bebas, daripada jalur ke file yang sudah ada.

Jika Anda ingin membuat file bernama deploy / resources.php yang memiliki pranala ke deploy / resources.build.php, Anda perlu memutuskan apakah Anda ingin membuat symlink absolut (yang tangguh terhadap symlink yang dipindahkan, tetapi rusak jika target dipindahkan), atau symlink relatif (yang akan tetap berfungsi selama symlink dan target dipindahkan bersama dan mempertahankan jalur relatif yang sama).

Untuk membuat symlink absolut, Anda bisa melakukan:

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

Untuk membuat yang relatif, pertama-tama Anda akan mencari tahu jalur relatif dari sumber ke target. Dalam hal ini, karena sumber dan target berada dalam direktori yang sama relatif terhadap satu sama lain, Anda dapat melakukannya:

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

Jika mereka tidak berada di direktori yang sama, Anda perlu melakukan sesuatu seperti:

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

Dalam hal ini, meskipun foodan barkeduanya berada di direktori Anda saat ini, Anda harus memasukkan a ../ke dalam ln target karena itu menggambarkan cara menemukan fdari direktori yang berisi b.

Itu penjelasan yang sangat panjang, tetapi mudah-mudahan ini membantu Anda memahami lnsintaks sedikit lebih baik.

godlygeek
sumber
3

Anda dapat membuat tautan dalam subkulit, sebagai berikut:

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

Ketika subkulit mengakhiri eksekusi, Anda akan menemukan diri Anda masih di direktori yang benar.

Atau, Anda dapat mencoba

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

yang juga berfungsi, mengabaikan untuk memasukkan dalam CL fakta bahwa file resources.build.php tidak ada di direktori di mana Anda mengeluarkan perintah, tetapi sebenarnya di dalam ./deploy .

MariusMatutiae
sumber
Ini ilmu hitam, tuan!
Kzqai
1

Ini membingungkan saya sampai saya menyadari symlink pada dasarnya adalah file konfigurasi. yaitu bagaimana saya akan menulis data jalur itu ke dalam file teks sederhana:

ln -s [target] [link name]

menjadi:

echo [target] > [link name]

Kesalahan yang saya (dan mungkin OP) membuat adalah dalam berpikir ln kebutuhan untuk mengetahui tentang file itu menargetkan. Aku tidak peduli. Hanya menulis beberapa informasi jalur ke file. Ini adalah masuk akal ln perintah:

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

Karenanya:

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

menghasilkan file simlink yang disebut resources.phpdi ./deployfolder yang mereferensikan file resources.build.phpdi folder ./deploy/deploy/.

Itu tidak seperti yang Anda inginkan dan memberikan tautan yang buruk (rusak). Tidak ada yang salah dengan tautannya, jika Anda meletakkan file itu di sana maka tautannya berfungsi. Namun, (seperti yang ditunjukkan oleh orang lain) yang saya dan OP inginkan adalah:

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