Тильда в пути не распространяется на домашний каталог

Скажем, у меня есть папка с именем 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"

Другие вопросы по тегам