Я пытаюсь понять интерполяцию Bash переменных.
Я хочу использовать, readlink
чтобы показать путь, на который указывает символическая ссылка.
Если я использую строку, это работает.
$ echo "$(readlink -- ~/.gitconfig)"
/Users/jord/.dotfiles/gitconfig
По какой-то причине это не работает, когда я пытаюсь использовать переменную вместо строки.
$ file="~/.gitconfig"
$ echo "$(readlink -- $file)"
Ничего не печатается, кроме пустой строки.
Если я сделаю то же самое, но с dirname
(в качестве примера) взамен, интерполяция переменных будет работать так, как я ожидал.
$ file="~/.gitconfig"
$ echo "$(dirname -- "$file")"
~
Что я делаю неправильно?
bash
bash-scripting
jordelver
источник
источник
echo "$(dirname -- "$file")"
? Почему не простоdirname -- "$file"
?echo $(stuff)
илиecho `stuff`
?Ответы:
~
в кавычках остается буквальным~
. Соответствующая часть Bash Reference Manual начинается сЧтобы увидеть разницу, сравните:
В вашем первом примере
$(…)
работает первым и в его контексте~
не цитируется. Так что это расширяется, как вы ожидаете.Ваш
$file
, когда он "не работает" содержит буквальное~
. Стандарт POSIX гласит :Поскольку раскрытие тильды выполняется до раскрытия параметра, переменная, которая расширяется
~/something
, не расширяется дальше по правильному пути.Помните,
~
или~/
в некоторых случаях это особенность вашей оболочки, но (почти?) Для любого другого инструмента это неверный путь. Когда это работает, это потому, что оболочка сначала выполняет свою «магию», а другой инструмент видит уже расширенный путь (например/Users/jord
).Обратите внимание, что в последнем примере расширение тильды не работает, вы все равно получаете литерал,
~
и оболочке уже слишком поздно что-то делать без дополнительных уловок (напримерeval
).dirname
не жалуется, потому что работает со строками. Ему все равно, является ли данный путь допустимым, существующим и т. Д. В основном он просто ищет последний компонент без косой черты и отбрасывает его с завершающими косыми чертами (если есть).Смотрите также этот ответ .
источник