Я знаю, что, возможно, об этом уже спрашивали, но я не смог найти его в Google.
Данный
- Ядро Linux
- Нет конфигураций, которые изменяют $ HOME
- удар
Будет ~ == $HOME
правдой?
bash
shell
environment-variables
home
PythonNut
источник
источник
~
это будет эквивалентно$HOME
любой среде POSIX; но я могу ошибатьсяecho "~"
иecho "$HOME"
.~
ни$HOME
. : P~
».) В любом случае, что-то, что нужно иметь в виду для случайного читателя, такого как я.Ответы:
Важно понимать, что
~
расширение - это особенность оболочки (некоторых оболочек), она не является магическим символом, а означает ваш домашний каталог, где бы он ни использовался.Он расширяется (оболочкой, которая является приложением, используемым для интерпретации командных строк), подобно
$var
расширению до его значения при некоторых условиях при использовании в командной строке оболочки перед выполнением команды.Эта функция впервые появилась в C-оболочке в конце 1970-х годов (у оболочки Bourne ее не было, равно как и у ее предшественницы - оболочки Томпсона), а затем была добавлена в оболочку Korn (более новую оболочку, построенную на оболочке Bourne в 80 - е годы). В конечном итоге он был стандартизирован POSIX и теперь доступен в большинстве оболочек, включая не POSIX, например
fish
.Поскольку он широко используется в оболочках, некоторые приложения, не относящиеся к оболочке, также распознают его как домашний каталог. Вот случай из многих приложений , в их файлах конфигурации или их собственной командной строки (
mutt
,slrn
,vim
...).bash
в частности (которая является оболочкой проекта GNU и широко используется во многих операционных системах на основе Linux), когда вызывается какsh
, в основном следует правилам POSIX о~
расширении, а в областях, не указанных в POSIX, ведет себя в основном как оболочка Korn (из который является частью клона).Хотя
$var
он раскрывается в большинстве мест (кроме внутри одинарных кавычек),~
расширение, будучи запоздалой мыслью, расширяется только в нескольких конкретных условиях.Он раскрывается по своему собственному аргументу в контекстах списка, в контекстах, где ожидается строка.
Вот несколько примеров того, как он расширяется
bash
:cmd arg ~ other arg
var=~
var=x:~:x
(требуется POSIX, используемый для таких переменных , какPATH
,MANPATH
...)for i in ~
[[ ~ = text ]]
[[ text = ~ ]]
(расширение~
принимается как образец в AT & T,ksh
но неbash
начиная с 4.0).case ~ in ~) ...
${var#~}
(хотя не в некоторых других оболочках)cmd foo=~
(хотя не тогда, когда вызывается какsh
, а только тогда, когда то, что слева,=
имеет формуbash
имени переменной без кавычек )cmd ~/x
(требуется POSIX, очевидно)cmd ~:x
(но неx:~:x
илиx-~-x
)a[~]=foo; echo "${a[~]} $((a[~]))"
(не в некоторых других оболочках)Вот несколько примеров, где это не раскрыто:
echo "~" '~'
echo ~@ ~~
(также обратите внимание, что~u
предполагается расширить до домашнего каталога пользователяu
).echo @~
(( HOME == ~ ))
,$(( var + ~ ))
extglob
:case $var in @(~|other))...
(хотяcase $var in ~|other)
все в порядке)../configure --prefix=~
(поскольку--prefix
не является допустимым именем переменной)cmd "foo"=~
(bash
из-за кавычек).sh
:export "foo"=~
,env JAVA_HOME=~ cmd
...Что касается того, что он расширяет:
~
один расширяет содержимоеHOME
переменной или, если он не установлен, домашний каталог текущего пользователя в базе данных учетных записей (как расширение, поскольку POSIX оставляет такое поведение неопределенным).Следует отметить, что в ksh88 и
bash
версиях, предшествующих 4.0, расширение тильды подверглось глобализации (генерации имени файла) в контексте списка:Это не должно быть проблемой в обычных случаях.
Обратите внимание, что, поскольку он расширен, то же самое предупреждение применяется как и другие формы расширений.
Не работает, если
$HOME
начинается с-
или содержит..
компоненты. Так что, хотя это вряд ли когда-либо будет иметь значение, строго говоря, нужно написать:Или даже:
(для покрытия значений
$HOME
вроде-
,+2
...) или просто:(так как
cd
вы попадете в ваш домашний каталог без всяких аргументов)Другие оболочки имеют более продвинутые
~
расширения. Например, уzsh
нас есть:~4
,~-
,~-2
(С завершением) используется для расширения каталогов в вашем стеке каталогов (места можноcd
раньше).~something
будет расширяться.источник
В любой версии Bash в любой системе, да .
~
как термин сам по себе определяется для расширения до:поэтому он всегда будет таким же, как
$HOME
и для текущей оболочки. Существует несколько других расширений тильды, например,~user
дляuser
домашнего каталога, но одно отдельное без кавычек~
всегда будет расширяться до"$HOME"
.Обратите внимание, что поведение в
~
и$HOME
может отличаться в некоторых случаях: в частности, если$HOME
содержит пробелы (или другие IFS символы), то$HOME
(без кавычек) будет расширяться до нескольких слов, в то время как~
это всегда одно слово.~
расширяется эквивалентно"$HOME"
(цитируется).Что касается вашего конкретного вопроса:
всегда верно, потому что
[[
подавляет разделение слов.[[ ~ == $HOME ]
может не быть, еслиHOME
есть символы соответствия шаблону , но[[ ~ == "$HOME" ]]
(то есть в кавычках"$HOME"
) всегда верно. Использование его в одинарных скобках может быть синтаксической ошибкой для значений,HOME
содержащих пробелы или специальные символы. Для любой разумной конфигурации домашний каталог~
и"$HOME"
то же самое и сравнивают как равные.Стефан Chazelas отметил случай в комментариях, где
~
и$HOME
дают разные значения: если выunset HOME
, то когда вы используете~
Bash вызоветgetpwuid
для считывания значения из базы паролей. Этот случай исключен вашим состоянием отсутствия изменений конфигурации$HOME
, но я упомяну его здесь для полноты.источник
/bin/sh
не менее, не может бытьbash
. Я не уверен , что Posixsh
спецификация говорит о~
~
.~
не было в оболочке Томсона или Борна (которые в свое время были доступны как/bin/sh
). Это не вrc
или его производных (где это используется для чего-то еще)bash
, еслиHOME
не установлено,~
расширяется до домашнего каталога пользователя из базы данных passwd. Так что это тот случай, когда~
не может расширяться до значения$HOME
.bash
раньше bash4 использовался для подстановки при расширении тильды (попробуйтеHOME='/*' bash -c 'echo /*'
). ТакHOME=/*; [ "$HOME" = ~ ]
бы вернул ошибку там.get_current_user_info
, которые используютсяgetpwuid
на всех платформах, кроме Tandem .