Я знаю, что, возможно, об этом уже спрашивали, но я не смог найти его в 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 argvar=~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; но я могу ошибаться