Тильда в пути не распространяется на домашний каталог
Скажем, у меня есть папка с именем Foo
находится в /home/user/
(мой /home/user
также представлены ~
).
Я хочу иметь переменную
a="~/Foo"
а затем сделать
cd $a
я получил-bash: cd: ~/Foo: No such file or directory
Однако если я просто сделаю cd ~/Foo
это работает отлично. Любая подсказка о том, как заставить это работать?
5 ответов
Вы можете сделать (без кавычек при назначении переменной):
a=~/Foo
cd "$a"
Но в этом случае переменная $a
не будет хранить ~/Foo
но расширенная форма /home/user/Foo
, Или вы могли бы использовать eval
:
a="~/Foo"
eval cd "$a"
Ты можешь использовать $HOME
вместо тильды (тильда расширяется оболочкой до содержимого $HOME
). Пример:
dir="$HOME/Foo";
cd "$dir";
Гораздо более надежным решением было бы использовать что-то вроде sed или, что еще лучше, расширение параметров bash:
somedir="~/Foo/test~/ing";
cd ${somedir/#\~/$HOME}
или если вы должны использовать Sed,
cd $(echo $somedir | sed "s#^~#$HOME#")
Хотя этот вопрос просто требует обходного пути, он указан как дубликат многих вопросов, которые спрашивают, почему это происходит, поэтому я думаю, что стоит дать объяснение. Согласно https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06:
Порядок раскрытия слов должен быть следующим:
Расширение тильды, расширение параметров, подстановка команд и арифметическое расширение должны выполняться от начала до конца.
Когда оболочка оценивает строку
cd $a
, он сначала выполняет раскрытие тильды (что не работает, поскольку не содержит тильды), затем расширяет
$a
к строке
~/Foo
, которая является строкой, которая окончательно передается в качестве аргумента в
cd
.
Если вы используете двойные кавычки, ~ будет сохранен как этот символ в $ a.
cd $ a не будет расширять ~, так как значения переменных не раскрываются оболочкой.
Решение:
eval "cd $ a"