Buat tautan simbolis ke nama path relatif

64

Aku bisa melakukan ini:

$ pwd
/home/beau
$ ln -s /home/beau/foo/bar.txt /home/beau/bar.txt
$ readlink -f bar.txt
/home/beau/foo/bar.txt

Tetapi saya ingin dapat melakukan ini:

$ pwd
/home/beau
$ cd foo
$ ln -s bar.txt /home/beau/bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Apakah ini mungkin? Bisakah saya entah bagaimana menyelesaikan relatif pathname dan meneruskannya ln?

Humphrey Bogart
sumber
Tetapi apa masalah yang akan diselesaikan dengan perilaku yang dijelaskan?
forcefsck
Nah, katakanlah Anda menawarkan folder terkompresi untuk diunduh, dan ingin memberikan instruksi yang dapat disalin-salin tentang cara menyinkronkan beberapa file folder.
Humphrey Bogart
2
ln -s $(pwd)/bar.txt ~/atau sertakan skrip instalasi.
forcefsck
2
tautan menyimpan sebenarnya nama yang Anda gunakan pada baris perintah. Resolusi nama itu untuk file dilakukan relatif terhadap lokasi tautan. Anda harus menggunakanln -s foo/bar.txt /home/beau/bar.txt
pqnet

Jawaban:

62

Jika Anda membuat tautan simbolis ke jalur relatif, itu akan menyimpannya sebagai tautan simbolis relatif, tidak absolut seperti contoh Anda. Ini umumnya hal yang baik. Tautan simbolis absolut tidak berfungsi saat sistem file dipasang di tempat lain.

Alasan contoh Anda tidak berfungsi adalah karena relatif terhadap direktori induk dari tautan simbolik dan bukan tempat lndijalankan.

Anda dapat melakukan:

$ pwd
/home/beau
$ ln -s foo/bar.txt bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Atau untuk itu:

$ cd foo
$ ln -s foo/bar.txt ../bar.txt

Sangat penting untuk menyadari bahwa argumen pertama setelah ln -sdisimpan sebagai target symlink. Ini bisa berupa sembarang string (dengan satu-satunya batasan yang tidak boleh kosong dan tidak bisa mengandung karakter NUL), tetapi pada saat symlink sedang digunakan dan diselesaikan, string itu dipahami sebagai jalur relatif ke jalur direktori induk dari symlink (ketika tidak dimulai dengan /).

penguin359
sumber
2
Kata dengan baik. Anda menjawab ini saat saya mengetik jawaban saya sendiri. :)
Shadur
Saya hanya punya pertanyaan yang sedikit berbeda - dan ini menjawabnya dengan sempurna. Saya ingin tahu bagaimana merujuk direktori home di symlink sehingga akan berfungsi ketika saya memindahkannya dari satu pengguna ke pengguna lain. Saya tidak yakin apakah sesuatu seperti itu ~akan berhasil.
Joe
"string itu dipahami sebagai jalur relatif ke direktori induk dari symlink" - ini menjelaskan semuanya!
Bojan Komazec
24

Jika Anda menggunakan coreutils yang lebih baru (Saya menggunakan coreutils-8.22-11), ia memiliki opsi untuk melakukan itu:

ln --help | grep relative

dapat menyimpan teks sewenang-wenang; jika nanti diselesaikan, tautan relatif adalah -r, --relative buat tautan simbolis relatif ke lokasi tautan

Sebagai contoh:

$ mkdir /tmp/test
$ touch /tmp/test/to
$ ln -rs /tmp/test/to /tmp/test/from
$ ls -l /tmp/test/from
    lrwxrwxrwx 1 ptr ptr 4 aug   25 17.02 /tmp/test/to -> from
ptr
sumber
Hm, bagi saya sepertinya tidak ada pilihan seperti itu -r. Menggunakan Mac.
ivkremer
1
@ivkremer sepertinya opsi ini tersedia sejak coreutils> = 8.16 (sumber: superuser.com/a/837935/403979 )
DJCrashdummy
Menggunakan bendera relatif sepertinya membersihkan masalah "terlalu banyak level tautan simbolis" yang saya alami.
Vix
12

Maaf tidak. Tautan simbolis relatif terhadap lokasi tautan, bukan lokasi Anda saat membuat tautan. Ada beberapa alasan bagus untuk perilaku ini, yang sebagian besar melibatkan pemasangan sistem file jarak jauh.

Shadur
sumber
7

Ada utilitas kecil yang nyaman disebut symlinks(awalnya oleh Mark Lords, sekarang dikelola oleh J. Brandt Buckley), hadir di banyak distribusi Linux.

Untuk mengonversi semua tautan simbolik absolut dalam direktori menjadi relatif:

symlinks -c /path/to/directory

Sayangnya tidak ada opsi untuk mengonversi satu tautan, Anda harus memindahkannya ke direktori sendiri terlebih dahulu.

mkdir ../tmp
mv link-to-relativize ../tmp
symlinks ../tmp
mv ../tmp/* .
rmdir ../tmp
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih. symlink tersedia di github . Dikelola oleh J. Brandt Buckley. v1.4.3 .
Evgeny Vereshchagin
3

Kamu bisa mencoba:

ln -s `pwd`/bar.txt /home/beau/bar.txt

Tapi, itu membuat tautan simbolis ke pathname absolut. Pertanyaan tekstual Anda menanyakan menyebutkan relatif pathname ...

Biasanya, nama path relatif adalah apa yang Anda inginkan, dan apa yang ln -smemberi Anda. Saya pikir yang Anda inginkan adalah:

cd /home/beau
ln -s foo/bar.txt bar.txt
MattBianco
sumber
1

Saat shell paling umum memperluas path, untuk membuat symlink relatif Anda harus mengutip "path sumber".

Juga, -sparameter artinya --symbolic. lnmembuat tautan keras secara default.

$ ln -s '../../relative_path' path
$ ls -al path

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path
emp.justine
sumber
0

Jika Anda yakin tidak ada kemungkinan poin mount Anda berubah, Anda dapat mencapai apa yang Anda coba lakukan dalam bash shell seperti ini:

ln -s `pwd`/bar.txt ~/bar.txt

Ini mengasumsikan bahwa Anda berada di direktori target ketika membuat tautan simbolik.

mreff555
sumber