Всегда ли равен $ HOME

Я знаю, что это, вероятно, было задано раньше, но я не мог найти его с Google.

Данный

  • Ядро Linux
  • Нет конфигураций, которые меняют $ HOME
  • удар

Будет ~ == $HOME быть правдой?

2 Solutions collect form web for “Всегда ли равен $ HOME”

Важно понимать, что ~ расширение является особенностью оболочки (некоторых оболочек), это не волшебный символ, а ваш домашний каталог, где он используется.

Он расширяется (оболочкой, которая является приложением, используемым для интерпретации команд), например, $var расширяется до своего значения при некоторых условиях, когда используется в командной строке оболочки до выполнения команды.

Эта функция впервые появилась в C-оболочке в конце 1970-х годов (оболочка Bourne не имела ее и не была ее предшественницей оболочки Thompson), позднее была добавлена ​​в оболочку Korn (более новая оболочка, построенная на оболочке Bourne в 80-е годы). В конечном итоге он был стандартизован POSIX и теперь доступен в большинстве оболочек, включая не-POSIX, такие как fish .

Поскольку это широко распространенное использование в оболочках, некоторые приложения, отличные от оболочки, также распознают его как домашний каталог. Это относится ко многим приложениям в файлах конфигурации или их собственной командной строке ( mutt , slrn , vim …).

bash (который является оболочкой проекта GNU и широко используется во многих операционных системах на базе Linux), когда он вызывается как sh , в основном следует правилам POSIX ~ расширения, а в областях, не указанных POSIX, ведет себя в основном как Korn shell (из которого он является клоном части), хотя см. ошибку, упомянутую ниже.

В то время как $var расширяется в большинстве мест (за исключением внутри одиночных кавычек), ~ расширение, будучи запоздалой мыслью, расширяется только в нескольких конкретных условиях.

Он расширяется, когда на свой собственный аргумент в контекстах списка, в контекстах, где ожидается строка.

Вот несколько примеров того, где он расширился в bash :

  • cmd arg ~ other arg
  • var=~
  • var=x:~:x (требуется POSIX, используется для переменных, таких как PATH , MANPATH …)
  • for i in ~
  • [[ ~ = text ]]
  • [[ text = ~ ]] ( ~ используется как шаблон в ksh но не bash ).
  • case ~ in ~) ...
  • ${var#~} (хотя и не в некоторых других оболочках)
  • cmd foo=~ (хотя и не при вызове как sh , и только когда то, что слева от = имеет форму имени без кавычек bash )
  • cmd ~/x (требуется, очевидно, POSIX)
  • cmd ~:x (но не x:~:x или x-~-x )
  • a[~]=foo; echo "${a[~]} $((a[~]))" 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 оставляет это поведение неопределенным).

Следует отметить, что в версиях 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 like - , +2 …) или просто:

 cd 

(поскольку cd приведет вас к вашему домашнему каталогу без каких-либо аргументов)

Другие оболочки имеют более расширенные расширения. Например, в zsh мы имеем:

  • ~4 , ~- , ~-2 (с завершением), используемый для расширения каталогов в стеке вашего каталога (места, к которым у вас раньше был cd ).
  • динамических названных каталогов . Вы можете определить свой собственный механизм, чтобы решить, как ~something то расширяется.

В любой версии Bash на любой системе, да . ~ как термин сам по себе определяется следующим образом:

Значение $ HOME

поэтому он всегда будет таким же, как любой $HOME для текущей оболочки. Существует несколько других расширений тильды, таких как ~user для домашней директории пользователя, но один незарегистрированный ~ по себе всегда будет расширяться до "$HOME" .

Обратите внимание, что поведение ~ и $HOME может быть различным в некоторых случаях: в частности, если $HOME содержит пробелы (или другие символы IFS ), то $HOME (без кавычек) будет расширяться до нескольких слов, а ~ всегда является одним словом , ~ расширяется эквивалентно "$HOME" (цитируется).

Что касается вашего конкретного вопроса:

 [[ $HOME == ~ ]] 

всегда верно, потому что [[ подавляет расщепление слов. [[ ~ == $HOME ] может и не быть, если у HOME есть символы соответствия шаблону , но [[ ~ == "$HOME" ]] (т. Е. Цитируется "$HOME" ) всегда истинно. Использование его внутри отдельных скобок может быть синтаксической ошибкой для значений HOME содержащих пробелы или специальные символы. Для любой разумной конфигурации домашнего каталога ~ и "$HOME" одинаковы и сравниваются как равные.


Стефан Chazelas отметил случай в комментариях, где ~ и $HOME дают разные значения: если вы unset HOME , тогда, когда вы используете ~ Bash, вызывается getpwuid для чтения значения из базы данных паролей. Этот случай исключается из-за вашего состояния отсутствия конфигурации с изменением $HOME , но я остановлюсь здесь на полноте.

  • xsel </ tmp / xselection не работает в скрипте
  • Неожиданная ошибка EOF и синтаксиса
  • Когда я cd через символическую ссылку, почему pwd показывает символическую ссылку вместо реального пути?
  • Запустите команду в интерактивной оболочке с помощью ssh после поиска .bashrc
  • команда: ls / etc | сортировать | grep d * не дает результатов, но ls / etc | сортировать | grep p * перечисляет всю директорию
  • find и sed (найти и заменить) вызывает незаконную последовательность байтов в Mac OS X
  • Как скопировать с подстановочным знаком в имя каталога?
  • Почему результат этого цикла for и while отличается?
  • cp, запущенный из результатов кода, не может stat '/ tmp / somedir' работает в оболочке
  • Найти файл с расширением .csv в каталоге, соответствующем шаблону
  • grep с переменной в переменной
  • Interesting Posts

    cd $ {DIR_PATH} возвращает «Нет такого файла или каталога»

    Объединить входные данные из нескольких файлов / труб без сбивающих линий или блокировки?

    настроить гостевую сеть в KVM для взаимодействия с внешним миром (google.com)

    Добавление sudo в команду find: что это значит?

    Простаивание процессора велико, но процессы изо всех сил стараются не отставать, как если бы процессор находился под большой нагрузкой

    Лучший способ просмотра сценариев журналов сеансов

    Разрешения на файлы для загруженных файлов

    Помощь в выборе ОС для высокопроизводительных вычислений

    Есть ли простой способ сделать эквивалент `sed …` заменяя одну и ту же строку несколькими значениями?

    Является ли моя удаленная оболочка по умолчанию проблемой?

    как отправить CTRL-ALT-Fn в виртуальную коробку гостевой Linux?

    Разрешение отклонено при получении файла md5sum с помощью сценария оболочки?

    Синхронизировать дерево каталогов с дедупликацией?

    Почему студия Android жалуется на OpenJDK?

    Как выполнить поиск максимальной глубины в ack и grep?

    Linux и Unix - лучшая ОС в мире.