Saya mencoba untuk meniru proses resolusi jalur (lihat halaman manual path_resolution) dalam sistem seperti unix.
OS saya adalah Linux dengan GNU coreutils 8.7.
Untuk memperjelas arti tambahan trailing '/' dalam resolusi, saya melakukan hal-hal berikut dalam shell:
mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link
Semuanya baik-baik saja, karena this_is_link adalah symlink, dan saya baru saja menghapusnya. Tetapi saat mencoba:
mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/
Itu bergema rm: cannot remove 'this_is_link/': Is a directory
Yah, jejak '/' menyebabkan mengikuti symlink, saya pikir. Jadi, saya mencoba perintah lain:rmdir this_is_link/
Dan hasil yang lucu keluar: rmdir: failed to remove 'this_is_link/': Not a directory
Bukan yang saya harapkan. Jadi saya meminta teman saya untuk mengkonfirmasi apakah hasil yang sama dapat diperoleh pada sistemnya. Dia memiliki versi coreutils yang lebih rendah daripada saya. Dan hasilnya luar biasa, tidak masalah rm
atau rmdir 'this_is_link/'
, kesalahan yang sama Not a directory
terjadi .
Dan teman lain baru mencobanya di Mac OS-nya, hasilnya adalah: rm
=> 'Is a directory', rmdir
=> direktori berhasil dihapus, tautannya tetap ada .
Apakah ada spesifikasi tentang perilaku yang tepat dari resolusi jalur?
Jawaban:
Spesifikasi POSIX / Single Unix menentukan bahwa nama path dengan garis miring harus merujuk ke direktori (lihat definisi dasar §4.11 resolusi nama path ).
foo/
sebenarnya didefinisikan setara denganfoo/.
(untuk tujuan resolusi jalur, bukan saat memanipulasi nama file;basename
dandirname
abaikan trailing slash). Sebagian besar implementasi menghargai hal ini, tetapi ada beberapa pengecualian.Ini menjelaskan perilaku
rm this_is_link/
: ini setara denganrm this_is_link/.
, di mana argumennya jelas sebuah direktori.rmdir this_is_link/
juga harus merujuk ke direktori. Itu tidak ada di komputer Anda adalah bug di GNU coreutils. OSX berperilaku benar di sini.sumber
Saya ambil:
Kebetulan, resolusi jalur tidak ada hubungannya dengan ini, sepertinya hanya '' rm '' memotong sudut daripada (benar) memanggil "stat" pada argumen (yang adalah apa yang dilakukan rmdir).
Bersulang.
sumber
rm
apakah panggilan stat (well, newfstatat, sebenarnya, denganAT_SYMLINK_NOFOLLOW
opsi) dan menolak untuk melanjutkan lebih jauh, sedangkan rmdir sebenarnya memanggil rmdir (2), tetapi mendapatENOTDIR
.AT_SYMLINK_NOFOLLOW
akan mencegahnya mengikuti symlink, jadi rm harus menghapus tautan itu sendiri alih-alih mencetak "Bukan direktori" yang tidak cocok dengan situasinya.stat
danstat -L
berbeda hanya jika argumen diberikan tanpa garis miring.rm
berperilaku dengan benar danrmdir
tidak. Trailing/
harus memaksa mereka untuk memperlakukan argumen mereka sebagai direktori, sesuai standar POSIX. Lihat jawaban saya untuk referensi .