Mengapa tilde (~) tidak berkembang ketika digunakan dengan argumen CLI yang dimulai dengan tanda hubung?

9

Saya kehilangan beberapa jam mencoba menjalankan server VNC (x0vncserver) dan klien menolak untuk terhubung dengan pesan aneh yang

No password configured for VNC Auth

Server juga mencetak kesalahan ini

 SVncAuth:    opening password file '~/.vnc/passwd' failed

Ok, saya membuang banyak waktu sampai saya menyadari bahwa tilde tidak diperluas oleh shell, maupun oleh x0vncserver. Lalu saya menjalankan tes ini

$ echo --PasswordFile=~/.vnc/passwd
--PasswordFile=~/.vnc/passwd

Tapi

$ echo PasswordFile=~/.vnc/passwd
PasswordFile=/home/tichomir/.vnc/passwd

Mengapa demikian? Mengapa shell menolak untuk memperluas tilde jika argumen dimulai dengan tanda hubung? Saya pikir tilde akan selalu berkembang selama tidak dikutip, tetapi ternyata ada aturan lain yang berlaku?

Tihomir Mitkov
sumber
Terkait: Perluasan tilde di zsh
Stéphane Chazelas
Lihat juga: Apakah ~ selalu sama dengan $ HOME
Stéphane Chazelas

Jawaban:

13

Ini adalah kekhasan bashshell yang dijelaskan dalam manualnya:

Bash juga melakukan ekspansi tilde pada kata-kata yang memenuhi persyaratan penugasan variabel (seperti yang dijelaskan di atas di bawah PARAMETER) ketika mereka muncul sebagai argumen untuk perintah sederhana. Bash tidak melakukan ini, kecuali untuk perintah deklarasi yang tercantum di atas, ketika dalam mode posix.

Ini berarti bahwa bash akan memperluas tilde di PasswordFile=~/.vnc/passwdstring Anda , karena itu argumen untuk echoyang tampak seperti penugasan variabel.

String --PasswordFile=~/.vnc/passwdtidak tampak seperti tugas variabel karena string --PasswordFilebukan nama variabel yang valid.

Catatan yang bashtidak melakukan ini ketika berjalan dalam mode POSIX, dan bahwa shell lain, seperti zsh, kshatau yashtidak melakukan ini secara default ( zshmemiliki magicequalsubstopsi untuk ekspansi tilde yang akan dilakukan setelah tanda sama dengan tanda kutip ( =) meskipun).

Jika Anda ingin memastikan bahwa jalur direktori home dari pengguna saat ini diperluas dengan benar sebagai bagian dari argumen ke perintah, gunakan $HOMEnilai alih-alih tilde:

echo --PasswordFile="$HOME/.vnc/passwd"

The "perintah deklarasi yang tercantum di atas" sebagaimana dimaksud dalam manual yang dibangun di perintah alias, declare, typeset, export, readonly, dan local.

Kusalananda
sumber
1
+1 | Saya tidak akan memikirkan itu.
LinuxSecurityFreak
Catatan: bash --posix -c '"export" a=~; printf "%s\n" "$a"'keluaran ~.
Stéphane Chazelas
2
Perhatikan bahwa ~yang diperluas alias a=~akan menjadi bug kepatuhan POSIX (dan tidak berguna). Tapi begitulah ksh88 melakukannya (yang berubah di ksh93) dan mungkin itulah sebabnya bash, zsh dan pdksh melakukannya juga. Mengapa yashyang ditulis terhadap spesifikasi POSIX tidak melakukannya.
Stéphane Chazelas
Ini adalah jawaban yang benar, tetapi pendekatan yang tepat seharusnya hanya menyediakan argumen opsi sebagai argumen terpisah, daripada bergabung dengan opsi menggunakan =menjadi satu argumen. Kemudian ekspansi tilde ada di awal kata dan pertanyaannya bisa diperdebatkan.
JdeBP
1
@ JdeBP, seperti yang terjadi, dalam kasus x0vncserver, x0vncserver --PasswordFile filetidak berfungsi, Anda perlu --PasswordFile=file.
Stéphane Chazelas