Apakah ada perbedaan antara jalur "file" dan "./file"?

12

Seperti judulnya, apakah ada perbedaan untuk * NIX filesystems? misalnya ls filedanls ./file

Sergey Alaev
sumber
1
Anda mungkin bertanya unix.stackexchange.com - jawaban sejauh ini semua memiliki informasi yang baik di dalamnya, tetapi tidak benar-benar terasa seperti itu jawabannya.
Rob Starling

Jawaban:

14

Saya tidak tergila-gila dengan penjelasan oleh SmallLoanOf1M. Secara teknis itu benar tetapi menjawab dengan cara yang tidak cocok dengan contoh penggunaan dalam pertanyaan.

Jadi sebagai contoh, berikut adalah satu perbedaan penting antara keduanya dari pertanyaan: "file" dan "./file"

Bagaimana jika file tersebut dinamai dengan karakter yang diuraikan oleh shell? Terutama mengenai karakter yang ditafsirkan oleh perintah yang sedang dijalankan.

Secara khusus, karakter "dash": "-". Tapi karakter lain bermakna bagi shell.

Contoh. File saya bernama "-dingle"

Coba daftar file:

ls -dingle
# ls -dingle
ls: invalid option -- 'e'

Lebih buruk lagi, bagaimana jika file itu bernama " -rf rmbomb *"? Sekarang coba hapus

rm "-rf rmbomb *"

Saya bahkan tidak akan mencoba menjalankan contoh itu, tetapi mudah-mudahan Anda mendapatkan idenya.

Jadi, bagaimana Anda mendaftar file menatap dengan tanda hubung? Gunakan ./di depan.

# ls ./-dingle
./-dingle

Ditto untuk rm

JDS
sumber
Itu adalah cara yang valid untuk memproses beberapa file dengan nama aneh, dan jawaban saya tidak mempertimbangkan file seperti itu. Orang juga bisa menggunakan literal sebagai gantinya dalam semua contoh di atas, dalam bentuk garis miring terbalik mendahului karakter aneh, termasuk spasi yang ditentukan di atas. Contohnya adalah: ls \-dingleatau ls \-rf\ rmbomb\ \*. Ini bisa menjadi cara yang baik untuk memastikan bahwa serangkaian perintah yang diberikan setidaknya konsisten, karena menentukan ./sebelum nama tidak akan keluar dari karakter setelah ./.
Spooler
2
Itu terjadi bahwa, karena lolos melarikan diri oleh shell, bukan perintah, dan params diurai oleh perintah, melarikan diri atau mengutip - tidak ada gunanya.
Dewi Morgan
2
Anda membuatnya terdengar seperti rm "-rf rmbomb *"benar-benar akan melakukan sesuatu yang buruk, bukan hanya membuat rmkesalahan cetak. Hanya berbahaya jika Anda lupa mengutip nama file, sehingga terjadi pemisahan kata. (esp. dalam shell script di mana Anda menjalankan rm $filebukannya rm "$file". Tapi dalam hal ini, *tidak akan berkembang, karena ekspansi gumpal tidak terjadi pada isi ekspansi variabel. Jika Anda ingin itu, Anda akan membutuhkan eval.) Lagi pula, jika skrip Anda memisahkan nama file sebelum meneruskan ke rm, saya akan membuat file bernama space -rf .atau sesuatu, jadi rm ./$itidak membantu.
Peter Cordes
1
BTW, pesan kesalahan yang sebenarnya adalah rm: invalid option -- ' ', dari ketika mencoba menafsirkan ruang setelah -rfsebagai saklar satu karakter, karena itu bagian dari argumen yang sama. (Dan ya, saya menjalankan ini di dalam direktori kosong kalau-kalau saya telah mengabaikan sesuatu dan itu sebenarnya berbahaya: P)
Peter Cordes
2
@PeterCordes: Wordplitting dan globbing DOES terjadi pada hasil ekspansi variabel yang tidak dikutip dan substitusi perintah, kecuali ditekan oleh IFS=''dan -fmasing - masing. Contoh yang lebih jarang adalah yang awkmemperlakukan operan (selain operan pertama yang merupakan skrip) yang memiliki bentuk foo=barsebagai tugas untuk dieksekusi tetapi ./foo=barsebagai file untuk dibaca.
dave_thompson_085
7

Iya.

Dengan mengeluarkan filepada baris perintah, BASH akan mencari variabel lingkungan $ PATH Anda untuk file dari nama itu. Kecuali file berada di direktori dalam variabel $ PATH Anda, itu tidak akan ditemukan.

.berarti direktori saat ini. ./berarti dalam direktori saat ini, secara relatif. Ini sama dengan mengatakan sesuatu seperti /home/sheogorath/shivering/isles.imgketika memohon ./isles.imgsaat bekerja di /home/sheogorath/shivering/direktori.

Dengan demikian, ini biasanya digunakan untuk mengeksekusi file dalam direktori kerja Anda "di tempat".

EDIT: Dalam contoh Anda, lsdipanggil oleh shell dan ditemukan dengan menggunakan variabel path. Argumennya akan diproses di direktori kerja Anda, apa pun itu. Karena ini adalah default untuk ls, Anda tidak akan melihat perbedaan antara menentukan filedan menentukan secara eksplisit ./filekarena keduanya menunjuk ke direktori Anda saat ini.

Tidak semua perintah akan menerima jalur file di direktori kerja, dan beberapa berharap Anda menyatakan file dalam direktori yang mereka tentukan sebelumnya melalui konfigurasi. Di antara perintah yang menerima file sebagai argumen, perintah ini kurang umum

Pengumpul informasi
sumber
1
Itu bash, tapi saya bertanya-tanya tentang resolusi jalur secara umum
Sergey Alaev
1
Ini adalah cara shell yang pernah saya dengar bekerja. BASH hanyalah yang paling umum digunakan.
Pengumpul informasi
4
$ PATH hanya relevan untuk perintah dan tidak ada hubungannya dengan argumen nama file yang mengikuti perintah seperti yang lsdisebutkan dalam pertanyaan asli. Itu lebih perbedaan antara mereferensikan jalur relatif (relatif terhadap direktori kerja saat ini) Yaitu ../../dir/filenamedan jalur absolut /path/to/dir/filename
HBruijn
1
+1 untuk Sheogorath ... dan jawaban yang benar.
Corey Ogburn
1
Jika mereka argumen ke perintah yang mencoba untuk menemukan file di direktori kerja secara default, mereka akan sama. Dengan demikian, karena lsmereka akan selalu menjadi jalan yang sama, yang ditentukan lebih eksplisit daripada yang lain. Tidak semua perintah berperilaku seperti ini saat memproses argumen, tetapi sebagian besar melakukannya.
Pengumpul informasi