Я знаю, что, возможно, об этом уже спрашивали, но я не смог найти его в Google.
Данный
- Ядро Linux
- Нет конфигураций, которые изменяют $ HOME
- удар
Будет ~ == $HOME
правдой?
echo "~"
и echo "$HOME"
.
~
ни $HOME
. : P
Я знаю, что, возможно, об этом уже спрашивали, но я не смог найти его в Google.
Данный
Будет ~ == $HOME
правдой?
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, расширение тильды подверглось глобализации (генерации имени файла) в контексте списка:
$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~
Это не должно быть проблемой в обычных случаях.
Обратите внимание, что, поскольку он расширен, то же самое предупреждение применяется как и другие формы расширений.
cd ~
Не работает, если $HOME
начинается с -
или содержит ..
компоненты. Так что, хотя это вряд ли когда-либо будет иметь значение, строго говоря, нужно написать:
cd -P -- ~
Или даже:
case ~ in
(/*) cd -P ~;;
(*) d=~; cd -P "./$d";;
esac
(для покрытия значений $HOME
вроде -
, +2
...) или просто:
cd
(так как cd
вы попадете в ваш домашний каталог без всяких аргументов)
Другие оболочки имеют более продвинутые ~
расширения. Например, у zsh
нас есть:
~4
, ~-
, ~-2
(С завершением) используется для расширения каталогов в вашем стеке каталогов (места можно cd
раньше).~something
будет расширяться.В любой версии Bash в любой системе, да . ~
как термин сам по себе определяется для расширения до:
Значение $ HOME
поэтому он всегда будет таким же, как $HOME
и для текущей оболочки. Существует несколько других расширений тильды, например, ~user
для user
домашнего каталога, но одно отдельное без кавычек ~
всегда будет расширяться до "$HOME"
.
Обратите внимание, что поведение в ~
и $HOME
может отличаться в некоторых случаях: в частности, если $HOME
содержит пробелы (или другие IFS символы), то $HOME
(без кавычек) будет расширяться до нескольких слов, в то время как ~
это всегда одно слово. ~
расширяется эквивалентно "$HOME"
(цитируется).
Что касается вашего конкретного вопроса:
[[ $HOME == ~ ]]
всегда верно, потому что [[
подавляет разделение слов. [[ ~ == $HOME ]
может не быть, еслиHOME
есть символы соответствия шаблону , но [[ ~ == "$HOME" ]]
(то есть в кавычках "$HOME"
) всегда верно. Использование его в одинарных скобках может быть синтаксической ошибкой для значений, HOME
содержащих пробелы или специальные символы. Для любой разумной конфигурации домашний каталог ~
и "$HOME"
то же самое и сравнивают как равные.
Стефан Chazelas отметил случай в комментариях, где ~
и $HOME
дают разные значения: если вы unset HOME
, то когда вы используете~
Bash вызовет getpwuid
для считывания значения из базы паролей. Этот случай исключен вашим состоянием отсутствия изменений конфигурации $HOME
, но я упомяну его здесь для полноты.
/bin/sh
не менее, не может быть bash
. Я не уверен , что Posix sh
спецификация говорит о~
~
. ~
не было в оболочке Томсона или Борна (которые в свое время были доступны как /bin/sh
). Это не в rc
или его производных (где это используется для чего-то еще)
bash
, если HOME
не установлено, ~
расширяется до домашнего каталога пользователя из базы данных passwd. Так что это тот случай, когда ~
не может расширяться до значения $HOME
.
bash
раньше bash4 использовался для подстановки при расширении тильды (попробуйте HOME='/*' bash -c 'echo /*'
). Так HOME=/*; [ "$HOME" = ~ ]
бы вернул ошибку там.
get_current_user_info
, которые используются getpwuid
на всех платформах, кроме Tandem .
~
это будет эквивалентно$HOME
любой среде POSIX; но я могу ошибаться