Это интересный. Подстановка $HOME
для ~
работает так же, как и удаление кавычек из назначения.
Если вы поставите set -x
в верхней части этого скрипта, вы увидите, что версия с кавычками устанавливает имя файла в ~/...
, то есть то, что присваивается -e
. Если вы удалите кавычки, имя файла будет расширенным /home/somebody/...
. Итак, в первом случае вы видите:
+ [ -e ~/... ]
и это не нравится. Во втором случае вы видите:
+ [ -e /home/somebody/... ]
и работает .
Если вы сделаете это без переменной, вы увидите:
+ [ -e /home/somebody/... ]
и, да, это работает.
После небольшого исследования я обнаружил, что на самом деле порядок, в котором bash
выполняет свои расширения. Со страницы руководства bash:
Порядок расширений: расширение фигурных скобок, расширение тильды, расширение параметров, арифметических и арифметических операций и подстановка команд (выполняется слева направо), разбиение слов и расширение пути.
Вот почему он не работает, переменная подставляется после расширения тильды. Другими словами, в точке, где bash
хочет расширить ~
, ее нет. Только после расширения переменной слово изменяется на ~/...
, и после этого расширение тильды не будет.
Одна вещь, которую вы могли бы сделать, - это изменить ваше if
утверждение на:
if [[ -e $(eval echo $filename) ]]; then
Это дважды оценит аргумент $ filename. В первый раз (с eval
) не будет ~
во время фазы расширения тильды, но $filename
будет изменено на ~/...
во время фазы переменного расширения.
Затем, во второй оценке (которая проводится как часть самого if
), ~
будет там во время фазы расширения тильды.
Я проверил это на моем .profile
файле, и он, кажется, работает, я предлагаю вам подтвердить в вашем конкретном случае.