Aturan sintaks jalur

10

Saya sedang menulis perpustakaan untuk memanipulasi string jalur Unix. Karena itu, saya perlu memahami beberapa sudut sintaksis yang tidak dikhawatirkan oleh kebanyakan orang.

Sebagai contoh, sejauh yang saya tahu, tampaknya itu foo/bardan foo//barkeduanya menunjuk ke tempat yang sama.

Juga, ~biasanya singkatan dari direktori home pengguna, tetapi bagaimana jika itu muncul di tengah jalan? Lalu apa yang terjadi?

Ini dan beberapa lusin pertanyaan tidak jelas lainnya perlu dijawab jika saya akan menulis kode yang menangani setiap kasus yang mungkin dengan benar. Adakah yang tahu referensi definitif yang menjelaskan aturan sintaksis yang tepat untuk hal ini?

(Sayangnya, mencari istilah seperti "Unix path syntax" hanya menghasilkan sejuta halaman yang membahas $PATHvariabel ... Heck, saya bahkan berjuang untuk menemukan tag yang cocok untuk pertanyaan ini!)

Matematika Matematika
sumber
ok ~ tilde dan -filename expansion mendasari fitur-fitur yang didefinisikan POSIX dari setiap lingkungan Unix. Beberapa tips: nama file bisa apa saja kecuali \ 0 atau /. ////// dan / adalah hal yang sama. $ PWD ditangani dalam kernel dan dapat dibaca untuk setiap proses (Linux) di / proc. /./ hanya dapat terjadi pada root dari path. Dalam $ PATH ::::: dan: adalah hal yang sama. / dev / null / dev / tty dan / tmp adalah jalur yang dijamin POSIX untuk setiap sistem konforman.
mikeserv
1
Sebagian besar pertanyaan Anda (tetapi bukan bagian tentang ~) tercakup dalam Bagaimana linux menangani pemisah banyak path (/ home //// username /// file) . Hal yang paling dekat dengan referensi normatif adalah spesifikasi POSIX atau Single Unix - tidak mudah dibaca.
Gilles 'SANGAT berhenti menjadi jahat'

Jawaban:

13

Ada tiga jenis jalur:

  • path relatif seperti foo, foo/bar, ../a, .. Mereka tidak memulai dengan /dan relatif terhadap direktori saat ini dari proses membuat panggilan sistem dengan jalur itu.
  • jalur absolut seperti /, /foo/baratau ///x. Mereka mulai dengan 1, atau 3 atau lebih /, mereka tidak relatif, dilihat mulai dari /direktori root.
  • POSIX memungkinkan //foountuk diperlakukan secara khusus, tetapi tidak menentukan caranya. Beberapa sistem menggunakannya untuk kasus khusus seperti file jaringan . Itu harus tepat 2 garis miring.

Selain pada awalnya, urutan garis miring bertindak seperti satu.

~hanya khusus untuk shell , itu diperluas oleh shell, itu tidak spesial untuk sistem sama sekali. Bagaimana itu diperluas tergantung pada shell. Kerang melakukan bentuk ekspansi lain seperti globbing ( *.txt) atau ekspansi variabel /$foo/$baratau lainnya. Sejauh menyangkut sistem ~foohanyalah jalur relatif seperti _fooatau foo.

Hal-hal yang perlu diingat:

  • foo/tidak sama dengan foo. Ini lebih dekat foo/.daripada foo(terutama jika foosymlink) untuk sebagian besar panggilan sistem pada sebagian besar sistem ( foo//sama seperti foo/olah).
  • a/b/../ctidak harus sama dengan a/c(misalnya jika a/bsymlink). Yang terbaik adalah tidak memperlakukan ..secara khusus.
  • umumnya aman untuk menganggap a/././././bsama a/b.
Stéphane Chazelas
sumber
Jadi secara ringkas, jika saya tidak peduli dengan manipulasi jalur shell (yang luas dan rumit), saya hanya perlu peduli /, .dan ..(?)
MathematicalOrchid
Contoh //foopenanganan ada di Cygwin, di mana digunakan untuk jalur UNC . Yaitu, //server/share/dir/file.txtadalah jalur hukum yang menunjukkan off-system secara default. Cygwin kembali ke sistem lokal jika tidak dapat menemukannya server.
Warren Young
3

Sebagai contoh, sejauh yang saya tahu, sepertinya foo / bar dan foo // bar keduanya menunjuk ke tempat yang sama.

Iya. Ini umum karena perangkat lunak kadang-kadang menyatukan jalur dengan asumsi bagian pertama tidak diakhiri dengan garis miring, sehingga orang dilemparkan untuk memastikan (artinya mungkin ada dua atau lebih). foo///bardan foo/////barjuga menunjuk ke tempat yang sama dengan foo/bar. Fungsi yang bagus untuk pustaka manipulasi lintasan akan menjadi yang mengurangi sejumlah garis miring berurutan menjadi satu (kecuali pada awal jalan, di mana ia dapat digunakan dalam cara URL-ish, atau, seperti ditunjukkan Stephane, untuk setiap tujuan khusus yang tidak ditentukan).

Juga, ~ biasanya merupakan direktori home pengguna

Transformasi itu dilakukan melalui exapansion shell dan tilde , yang hanya berfungsi jika itu adalah karakter pertama di jalan. Apakah Anda perlu menangani ini atau tidak, tergantung pada konteksnya. Jika pustaka akan digunakan dengan program normal yang menerima, misalnya, argumen baris perintah yang berisi jalur, tilde ekspansi sudah dilakukan ketika mereka melihat jalan. Satu-satunya situasi yang saya anggap sebagai masalah adalah jika Anda memproses jalur langsung dari file teks.

Di luar itu, ~adalah karakter hukum di jalur * nix dan tidak boleh diubah ke yang lain. Sesuai dengan ini , satu-satunya karakter yang tidak legal dalam nama file unix adalah /(karena itu adalah pemisah path) dan "null" (alias. Nol byte) karena mereka ilegal dalam teks pada umumnya.

goldilocks
sumber
+1 untuk penjelasan ekspansi tilde; Saya tidak tahu Anda bisa merujuk pengguna lain dengan itu!
MathematicalOrchid
2
Seperti yang dikatakan Stephane, Anda tidak bisa membabi buta semua garis miring ke depan yang berulang. Beberapa garis miring ke depan pada awal jalan harus diperlakukan dengan hati-hati.
Warren Young
@ WarrenYoung Diedit untuk memperjelas ini. PS. Meneruskan??! O_O
goldilocks
Lebih baik, meskipun saya tidak akan mengatakan ini ada hubungannya dengan URL. UNC kembali ke akhir 1980-an, sementara URL tidak muncul sampai bertahun-tahun kemudian.
Warren Young
@ WarrenYoung Cukup adil, meskipun tampaknya UNC khusus untuk platform MS , jadi //secara teknis juga tidak begitu. Baik URL dan yang lebih baru, menurut-ke-SC spec ambigu bebas untuk // mungkin telah diturunkan dari itu, dalam hal ini "URL-ish" tampaknya label yang cocok untuk konvensi (bahkan jika UNC lebih tua, dan bahkan jika kemiripannya tidak disengaja). Saya tidak akan pernah mengatakan bahwa "mereka adalah URL", hanya itu //atau \\ melayani tujuan "URL-ish".
goldilocks