Persen dalam variabel lingkungan $ PATH

16

$ PATH saya terlihat seperti ini:

/home/torbjorr/deployed/vector/x86_64-GNU%2fLinux:/home/torbjorr/deployed/typewriter/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mustudio/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mathext/x86_64-GNU%2fLinux:/home/torbjorr/deployed/doxymax/x86_64-GNU%2fLinux:/home/torbjorr/deployed/c2tex/x86_64-GNU%2fLinux:/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand:/home/torbjorr/deployed/x86_64-GNU%2fLinux/spellesc:/home/torbjorr/deployed/x86_64-GNU%2fLinux/projinit:/home/torbjorr/deployed/x86_64-GNU%2fLinux/herbs:/home/torbjorr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Dalam bash, saya bisa tanpa masalah memanggil tongkat yang terletak di

/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand

Suka

$ wand
(i) Mål från "main.cpp" har registrerats
(i) Skapar katalog "__wand_targets_dbg"
(i) Kör g++ "main.cpp" -fpic -L"/home/torbjorr/deployed"  -g -Wall -std=c++11 -I"/home/torbjorr/deployed" -o "__wand_targets_dbg/cb-template

Namun, dalam mode kompatibilitas shell bourne, tongkat tidak dapat ditemukan:

$ wand
sh: 2: wand: not found

Sepertinya masalahnya adalah tanda% di jalur ini. Tanda ini telah ditambahkan oleh penyandian URL sehingga nama "GNU / Linux" dapat digunakan dalam nama direktori meskipun itu bukan nama file yang valid. Apakah mungkin untuk membuat nama berfungsi di sh, atau menjadikan perintah sh bekerja sebagai bash. Yaitu, buat bash berperilaku sama meskipun dipanggil dengan perintah / bin / sh, yang tetap terhubung dengan bash.

pengguna877329
sumber
Pertanyaan yang bagus Tampaknya bahwa '%' karakter tidak bekerja dengan benar di $ PATH dari sh(ok di bashdan zshmeskipun). Langsung memanggil karya yang dapat dieksekusi di sh; sangat aneh.
Rmano
Apa yang terjadi jika Anda menggunakan 2 %%?
mikeserv
Atau melarikan diri%?
mdpc

Jawaban:

15

Itu bukan shell Bourne, atau bashmeniru shell Bourne, itu shell Almquist, dalam kasus Anda mungkin shell Debian Almquist (garpu Linux oleh Debian dari BSD sendiri berdasarkan shell Almquist asli).

Dalam shell Almquist (yang asli dan versi modern), %digunakan PATHuntuk fitur tambahan khusus ash. Mengutip dari dokumentasi:

Pencarian Jalur

Saat menemukan perintah, shell pertama-tama melihat apakah ia memiliki fungsi shell dengan nama itu. Kemudian, jika PATH tidak mengandung entri %builtin, ia mencari perintah builtin dengan nama itu. Akhirnya, pencarian setiap entri di PATH pada gilirannya untuk perintah.

Nilai variabel PATH harus berupa serangkaian entri yang dipisahkan oleh titik dua. Setiap entri terdiri dari nama direktori, atau nama direktori diikuti oleh bendera yang dimulai dengan tanda persen. Direktori saat ini harus ditandai dengan nama direktori kosong. Jika tidak ada tanda persen, maka entri menyebabkan shell untuk mencari perintah di direktori yang ditentukan. Jika flag tersebut %builtin maka daftar perintah builtin shell dicari. Jika flag tersebut %func maka direktori dicari file yang dibaca sebagai input ke shell. File ini harus mendefinisikan fungsi yang namanya adalah nama perintah yang dicari.

Nama perintah yang berisi garis miring dieksekusi tanpa melakukan pencarian di atas.

Kerang lain suka kshatau zshmemiliki autoloading yang sama dari mekanisme fungsi, tetapi mereka menggunakan variabel yang berbeda ( $FPATH), tetapi Anda tidak bisa menentukan fungsi atau executable mana yang diutamakan.

Dalam kasus Anda, /home/torbjorr/deployed/vector/x86_64-GNU%2fLinuxditafsirkan sebagai /home/torbjorr/deployed/vector/x86_64-GNUdirektori dengan 2fLinuxbendera. Bendera itu diabaikan karena tidak diketahui.

Tidak ada cara selain itu. Sekalipun abu memiliki mekanisme melarikan diri sehingga ini %tidak diperlakukan secara khusus, maka ia tidak akan bekerja di kulit lain atau benda lain yang terlihat $PATHseperti execvp().

Anda harus menghapus %karakter dari $PATH, jadi ganti nama direktori Anda atau tambahkan symlink.

Atau jangan gunakan ashuntuk Anda /bin/sh. Implementasi shell POSIX ringan lainnya yang tidak termasuk yashdan mksh.

Stéphane Chazelas
sumber
Meskipun jawaban ini memberikan penjelasan, itu tidak memberikan solusi. Apakah ada cara yang kompatibel untuk menjaga%.
user877329
@ user877329, tidak ada solusi nyata di sini. Lihat hasil edit saya.
Stéphane Chazelas
3
Dengan kata lain, Debian shmelanggar standar POSIX. Mengingat bahwa titik memiliki terpisah shadalah persis bahwa Anda harus yakin untuk tidak tersandung beberapa ekstensi shell yang tidak kompatibel (saya kira tidak ada yang menggunakan /bin/shsebagai shell login hari ini), saya akan mempertimbangkan bug.
celtschk
1
@celtschk, setuju meskipun titik penggunaan ashuntuk / bin / sh lebih untuk menghindari hukuman kinerja menggunakan bash, jadi menggunakan yashatau mksh(atau poshjika Anda ingin mengecualikan semua ekstensi) masih merupakan opsi yang lebih baik daripada menggunakan bash. Juga, orang dapat menganggapnya sebagai kasus sudut. Tidak ada yang biasanya memiliki %komponen jalur. Sebagian besar cangkang memiliki kasing sudut yang tidak sesuai dengan POSIX.
Stéphane Chazelas
1
@mtmiller, bukan itu cara saya membaca arti dari set nama file portabel (PFCS). POSIX menentukan API pemrograman tetapi bukan implementasi sistem file. PFCS adalah jaminan POSIX minimum yang akan berfungsi apa pun sistem file, apa pun lokal saat ini tetapi tidak ada alasan untuk alat untuk tidak menerima karakter dalam nama file jika didukung oleh sistem file dan berlaku di lokal saat ini. Perhatikan bahwa misalnya POSIX mengharuskan ada [perintah meskipun karakter itu tidak ada di PFCS.
Stéphane Chazelas