Всегда ли равен $ 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 , но я остановлюсь здесь на полноте.

  • Как выполнить время параллельных команд
  • команда $ (ls / usr / bin / * | grep zip) дает мне ошибки. Что не так?
  • Перенесите stderr и stdout в / dev / null с помощью / bin / sh
  • Как перемещать файлы во вновь созданный каталог при условии в shell / perl
  • Где сохранить временные файлы для сценариев оболочки
  • Почему ядро ​​убивает мой процесс с отключением при выходе из системы?
  • Есть ли улучшенная версия «pick», которая будет работать с именами файлов с пробелами?
  • Как избежать одиночной цитаты?
  • Удаление строк путем сопоставления только 3-го и 4-го символов
  • Завершить второй (параллельный) процесс, если первый из них завершен
  • Объясните команду оболочки: shift $ (($ optind - 1))
  • Interesting Posts

    Как использовать команду чтения с вопросом и переменной alltogether?

    Audio Controller не работает на linux mint

    openvpn ПРЕДУПРЕЖДЕНИЕ: не был проверен метод проверки сервера

    настройка открытого ключа ssh

    Как найти пакеты только, какое имя пакета равно тексту с aptitude?

    linux: Есть ли способ сбросить очередь выполнения задачи?

    Trick для создания ограниченного пользователя linux. Я могу удаленно управлять независимо от того, где он подключается.

    Как перенаправить X поверх SSH для удаленного запуска графических приложений?

    «python-software-properties» не имеет кандидата на установку при установке факела

    Где найти эту инструментальную цепочку?

    Arch: не удается использовать pacman: ошибка при загрузке разделяемых библиотек

    Создание каталога, защищенного от 'rm -rf'

    Запуск приложения из терминала

    Не удалось получить доступ к Интернету, если включен беспроводной доступ

    Как отслеживать, почему клавиши быстрого доступа X11 не работают?

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