Чому tilde (~) не розширюється при використанні аргументу CLI, починаючи з тире?


9

Я програв пару годин, намагаючись запустити сервер VNC (x0vncserver), і клієнт відмовився з'єднатися із дивним повідомленням, що

No password configured for VNC Auth

Сервер також друкує цю помилку

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

Гаразд, я витратив багато часу, поки не зрозумів, що тильда не була розширена ні оболонкою, ні x0vncserver. Потім я провів ці тести

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

Але

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

Чому так? Чому оболонка відмовляється розширювати тильду, якщо аргумент починається з тире? Я думав, що тильда завжди буде розширюватися до тих пір, поки її не цитують, але, мабуть, є ще одне правило, яке вступає в гру?



Відповіді:


13

Це особливість bashоболонки, описаної в її посібнику:

Bash також виконує розширення нахилу на слова, що задовольняють умовам присвоєння змінних (як описано вище в PARAMETERS), коли вони з'являються як аргументи простим командам. Bash цього не робить, за винятком команд декларації, перерахованих вище, коли в режимі posix.

Це означає , що bash буде розширювати тильди у вашій PasswordFile=~/.vnc/passwdрядку, так як це аргумент для того, echoщо виглядає як привласнення змінної.

Рядок --PasswordFile=~/.vnc/passwdне схожий на призначення змінної, оскільки рядок --PasswordFileне є дійсним ім'ям змінної.

Зауважте, що bashце не робиться під час запуску в режимі POSIX, і що інші оболонки, як-от zsh, kshабо yashне роблять цього за замовчуванням ( хоча zshє magicequalsubstможливість розширення нахилу, яке слід виконувати після нецитованих знаків рівності ( =), хоча).

Якщо ви хочете переконатися, що шлях домашнього каталогу поточного користувача належним чином розширений як частина аргументу команди, використовуйте $HOMEзначення замість тильди:

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

«Декларація команди , перераховані вище» , згадані в керівництві, вбудовані команди alias, declare, typeset, export, readonly, і local.


1
+1 | Я б не думав про це.
LinuxSecurityFreak

Хоча примітка: bash --posix -c '"export" a=~; printf "%s\n" "$a"'результати ~.
Стефан Шазелас

2
Зауважте, ~що розширення в alias a=~буде помилкою відповідності POSIX (і не корисно). Але саме так ksh88 зробив це (що змінилося в ksh93), і, ймовірно, тому bash, zsh та pdksh роблять це також. Чому те, yashщо було написано проти специфікації POSIX, цього не робить.
Стефан Хазелас

Це правильна відповідь, але правильним підходом було б просто подати аргумент опціону як окремий аргумент, а не об'єднати з варіантом, використовуючи =один аргумент. Тоді розширення тильди - на початку слова, і питання суперечить.
JdeBP

1
@JdeBP, як це буває, у випадку x0vncserver, x0vncserver --PasswordFile fileне працює, вам потрібно --PasswordFile=file.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.