Saya ingin memasukkan perintah ke skrip shell yang akan membuat symlink ke direktori, tetapi skrip ini bisa dijalankan berulang-ulang, jadi pada pemanggilan berikutnya, perintah itu tidak boleh mengubah apa pun.
Berikut adalah struktur direktori:
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
Saya ingin membuat symlink di foo/
snippet yang disebut yang menunjuk ke direktori /tmp/test_symlink/repo/resources/snippets
.
Jadi saya jalankan:
% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
yang memberikan hasil yang diinginkan.
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
│ └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
5 direktori, 5 file
Namun, ketika perintah dijalankan lagi,
% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
itu menciptakan symlink ke direktori, di mana symlink aleady menempatkan symlink di dalam direktori nyata
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
│ └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets -> /tmp/test_symlink/repo/resources/snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
mengapa ini terjadi dan bagaimana saya bisa memodifikasi perintah sehingga doa berikutnya tidak akan membuat efek aneh ini?
sumber
-n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory
.-T, --no-target-directory treat LINK_NAME as a normal file always
Menurut Anda apakah lebih baik memperlakukan symlink sebagai file selalu? Saya akan berpikir akan lebih baik untuk membatasi penggunaan opsi "khusus" ini?-T
adalah bagaimana Anda membuatln
idempoten. Ada cara lain untuk mendapatkan hasil yang sama jika Anda mau, seperti menghapus tautan dan membuatnya kembali, atau jika Anda sudah tahufoo
,ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/
(sebenarnya itu mungkin jawaban yang lebih baik sama sekali, saya akan memperbarui).if
pernyataan untuk mendeteksi keberadaan symlink dan melewatkan perintah jika symlink ada, tetapi skrip akhirnya menjadi berantakan dan sulit dibaca, saya mencari sesuatu yang idempoten tetapi sederhana, sepertimkdir -p
tidak menggunakan tes , tidak ada logika, hanya bagus satu baris :)-T
, tetapi akhir jawaban saya menyajikan solusi lain yang tidak digunakan-T
.Terbaik yang bisa saya katakan apa yang terjadi di sini adalah bahwa pada pass kedua
ln
perintah berperilaku seperticp
ataumv
, yaitu jika ia melihat "direktori" di <destination> ia akan meletakkan file di dalamnya, kalau tidak, <destination> tidak ada, itu akan membuat <destination>. (yang mana trik "slashdot" terhindar - artinya trik <destinasi> ada dan merupakan direktori).Tapi saya bisa saja salah.
Dalam kedua kasus ini tampaknya berhasil
sumber