Apakah ada sistem operasi yang menyediakan mekanisme (panggilan sistem - bukan program baris perintah) untuk mengubah nama jalur yang direferensikan oleh tautan simbolis (symlink) - selain dengan memutuskan tautan yang lama dan membuat yang baru?
Standar POSIX tidak. Solaris 10 tidak. MacOS X 10.5 (Leopard) tidak. (Saya cukup yakin baik AIX maupun HP-UX tidak melakukannya. Dilihat dari daftar panggilan sistem Linux ini , Linux juga tidak memiliki panggilan sistem seperti itu.)
Apakah ada yang bisa?
(Saya mengharapkan jawabannya adalah "Tidak".)
Karena sulit membuktikan negatif, mari susun ulang pertanyaannya.
Jika Anda mengetahui bahwa beberapa sistem operasi (mirip-Unix) yang belum terdaftar tidak memiliki pemanggilan sistem untuk menulis ulang nilai symlink (string yang dikembalikan oleh readlink()
) tanpa menghapus symlink lama dan membuat yang baru, tambahkan - atau mereka - dalam sebuah jawaban.
ln
perintah (atau API yang setara) menimpa tautan lama? Masalah apa yang Anda hadapi?Jawaban:
AFAIK, tidak, Anda tidak bisa. Anda harus menghapusnya dan membuatnya kembali.Sebenarnya, Anda dapat menimpa sebuah symlink dan dengan demikian memperbarui nama jalur yang dirujuk olehnya:EDIT : Seperti yang ditunjukkan OP dalam komentar, menggunakan
--force
opsi ini akan membuatln
panggilan sistem keunlink()
sebelumnyasymlink()
. Di bawah ini, outputstrace
di kotak linux saya membuktikannya:Jadi saya kira jawaban akhirnya adalah "tidak".EDIT : Berikut ini disalin dari jawaban Arto Bendiken di unix.stackexchange.com, sekitar tahun 2016.
Ini dapat memang dilakukan atom dengan
rename(2)
, dengan terlebih dahulu menciptakan symlink baru di bawah nama sementara dan kemudian bersih Timpa symlink lama dalam satu pergi. Seperti yang dinyatakan halaman manual :Di shell, Anda akan melakukan ini dengan
mv -T
sebagai berikut:Anda dapat melakukan
strace
perintah terakhir itu untuk memastikannya memang menggunakan direname(2)
bawah tenda:Perhatikan bahwa di atas, keduanya
mv -T
danstrace
khusus untuk Linux.Di FreeBSD, gunakan secara
mv -h
bergantian.Catatan editor: Beginilah cara Capistrano melakukannya selama bertahun-tahun sekarang, sejak ~ 2.15. Lihat permintaan tarik ini .
sumber
Ya kamu bisa!
sumber
-f
berarti opsi 'menghapus tujuan yang ada' sebelum membuat yang baru. Jadi, perintah ini mencapai hasil, tetapi dengan melakukanunlink(2)
diikuti olehsymlink(2)
. Ini bukanlah tentang pertanyaan aslinya. Juga perhatikan bahwa jawaban yang diterima dan jawaban yang paling banyak dipilih berikutnya keduanya digunakanln -sf
untuk melakukan pekerjaan itu, tetapi seperti yangstrace
ditunjukkan oleh output, itu dilakukanunlink()
dansymlink()
karena tidak ada panggilan sistem untuk mengubah symlink.Tidak perlu memutuskan tautan symlink lama secara eksplisit. Kamu bisa melakukan ini:
(atau gunakan symlink yang setara dan ganti nama panggilan). Ini lebih baik daripada membatalkan tautan secara eksplisit karena penggantian nama bersifat atomik, sehingga Anda dapat yakin bahwa tautan akan selalu mengarah ke target lama atau baru. Namun ini tidak akan menggunakan kembali inode asli.
Pada beberapa sistem file, target dari symlink disimpan dalam inode itu sendiri (menggantikan daftar blokir) jika cukup pendek; ini ditentukan pada saat dibuat.
Mengenai pernyataan bahwa pemilik dan grup sebenarnya tidak material, symlink (7) di Linux mengatakan bahwa ada kasus di mana itu signifikan:
sumber
set -x -e; mkdir junk; ( cd junk; mkdir olddir newdir; ln -s olddir mylink; ls -ilR; ln -s newdir temp; ls -ilR; mv temp mylink; ls -ilR; ); rm -fr junk
. Jika Anda membuat file oldfile dan newfile alih-alih direktori dan menjalankan skrip yang setara (terutama mengubah olddir ke oldfile, newdir ke newfile), maka Anda mendapatkan efek yang Anda harapkan. Hanya satu kerumitan ekstra! Terima kasih atas tanggapannya.Sekadar peringatan untuk jawaban yang benar di atas:
Menggunakan Metode -f / --force memberikan risiko kehilangan file jika Anda mencampuradukkan sumber dan target:
Tentu saja ini memang disengaja, tetapi biasanya kesalahan terjadi. Jadi, menghapus dan membangun kembali symlink sedikit lebih banyak pekerjaan tetapi juga sedikit hemat:
yang setidaknya menyimpan file saya.
sumber
-f
atau--force
selalu sedikit berbahaya; itu menganggap pengguna tahu tentang apa mereka. Ini sangat mematikan jika Anda menggunakannya secara biasa (rm -fr …
setiap saat berbahaya).Bukankah membatalkan tautannya dan membuat yang baru pada akhirnya akan melakukan hal yang sama?
sumber
ln --force
perintah ini benar-benar akan menimpa tautan yang ada.ln (1)
, sementara matt b. membahas fakta bahwasymlink (2)
tidak tidak mendukung Timpa. Anda berdua benar, dan saya akan menyarankan bahwa melihat implementasiln (1)
akan memberikan cara paling idomatis untuk menyelesaikan prosedur unlink-relink.Untuk berjaga-jaga jika itu membantu: ada cara untuk mengedit symlink dengan midnight commander (mc). Perintah menu adalah (dalam bahasa Prancis di antarmuka mc saya):
yang dapat diterjemahkan ke:
Pintasannya adalah Cx Cs
Mungkin secara internal menggunakan
ln --force
perintah, saya tidak tahu.Sekarang, saya mencoba menemukan cara untuk mengedit banyak symlink sekaligus (begitulah cara saya sampai di sini).
sumber
unlink()
diikuti oleh asymlink()
, hanya karena itulah yang disediakan oleh sistem mirip Unix.Secara teknis, tidak ada perintah bawaan untuk mengedit tautan simbolik yang ada. Ini dapat dengan mudah dicapai dengan beberapa perintah singkat.
Ini sedikit fungsi bash / zsh yang saya tulis untuk memperbarui tautan simbolik yang ada:
sumber
unlink()
dansymlink()
dengan nilai baru, yang terjadi di balik layar dengan kode Anda. Secara pribadi, saya akan meminta fungsi tersebut menuntut tepat dua (atau mungkin kelipatan dari dua) argumen dan jaminan jika pemanggilan tidak benar. Itu perspektif khusus.