Membuntuti garis miring pada tautan simbolis ke direktori

8

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 rmatau rmdir 'this_is_link/', kesalahan yang sama Not a directoryterjadi .

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?

ymfoi
sumber

Jawaban:

7

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 dengan foo/.(untuk tujuan resolusi jalur, bukan saat memanipulasi nama file; basenamedan dirnameabaikan trailing slash). Sebagian besar implementasi menghargai hal ini, tetapi ada beberapa pengecualian.

Ini menjelaskan perilaku rm this_is_link/: ini setara dengan rm 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.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Inilah yang saya butuhkan, terima kasih kawan!
ymfoi
-1

Saya ambil:

  • '' rm link / '' gagal karena rm melihat char terakhir, melihatnya slash, memberikan (tidak benar-benar benar) diagnostik yang Anda lihat;
  • '' rmdir link / '' gagal baik-baik saja: tautan bukan direktori, ini adalah symlink
  • '' tautan rm '' akan berhasil dengan benar

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.

Bentuk Kehidupan Alien
sumber
1
Sebenarnya, yang sebaliknya tampaknya benar: rmapakah panggilan stat (well, newfstatat, sebenarnya, dengan AT_SYMLINK_NOFOLLOWopsi) dan menolak untuk melanjutkan lebih jauh, sedangkan rmdir sebenarnya memanggil rmdir (2), tetapi mendapat ENOTDIR.
Ansgar Esztermann
@AnsgarEsztermann AT_SYMLINK_NOFOLLOWakan mencegahnya mengikuti symlink, jadi rm harus menghapus tautan itu sendiri alih-alih mencetak "Bukan direktori" yang tidak cocok dengan situasinya.
ymfoi
Dari pemeriksaan singkat dengan stat (1), garis miring akan menimpa opsi. Output dari statdan stat -Lberbeda hanya jika argumen diberikan tanpa garis miring.
Ansgar Esztermann
@AnsgarEsztermann Oh, begitu ... Thx. Bagaimana dengan efek yang berbeda pada lingkungan yang berbeda? Ada ide?
ymfoi
1
Sebaliknya: pada mesin ymfoi, rmberperilaku dengan benar dan rmdirtidak. Trailing /harus memaksa mereka untuk memperlakukan argumen mereka sebagai direktori, sesuai standar POSIX. Lihat jawaban saya untuk referensi .
Gilles 'SANGAT berhenti menjadi jahat'