Я знаю, що про це, ймовірно, питали і раніше, але я не зміг його знайти в Google.
Дано
- Ядро Linux
- Немає конфігурацій, які змінюють $ HOME
- баш
Чи ~ == $HOMEбуде правдою?
echo "~"і echo "$HOME".
~ані $HOME. : P
Я знаю, що про це, ймовірно, питали і раніше, але я не зміг його знайти в Google.
Дано
Чи ~ == $HOMEбуде правдою?
echo "~"і echo "$HOME".
~ані $HOME. : P
Відповіді:
Що важливо розуміти, це те, що ~розширення є особливістю оболонки (деяких оболонок), це не магічний символ, а значить ваш домашній каталог, де б він не використовувався.
Він розширюється (оболонкою, що є додатком, що використовується для інтерпретації командних рядків), подібно $varдо деяких значень, коли використовується в командному рядку оболонки перед виконанням команди.
Ця особливість вперше з'явилася в C-оболонці в кінці 1970-х (оболонки Борна її не було, як ні у попередника оболонки Томпсона), пізніше була додана до шкаралупи Корна (новішої оболонки, побудованої на оболонці Борна в 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 розширення tilde зазнало глобалізації (генерація імені файлу) у списках:
$ 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домашнього каталогу «S, але один незгаданих ~сама по собі завжди буде розширюватися "$HOME".
Зверніть увагу , що поведінка в ~і $HOMEможе відрізнятися в деяких випадках: зокрема, якщо $HOMEмістить прогалини (або інші IFS символи), то $HOME(без лапок) буде розширюватися до декількох слів, в той час як ~це завжди одне слово. ~розширюється рівнозначно "$HOME"(цитується).
Що стосується вашого конкретного питання:
[[ $HOME == ~ ]]
завжди правда, тому що [[ пригнічує розбиття слів. [[ ~ == $HOME ]може не бути, якщо в ньому HOMEє символи, що відповідають шаблону , але [[ ~ == "$HOME" ]](тобто, цитується "$HOME") це завжди вірно. Використання його всередині окремих дужок може бути синтаксичною помилкою для значень, HOMEщо містять пробіли або спеціальні символи. Для будь-якої розсудливої конфігурації домашньої директорії ~і "$HOME"є однаковими і вважаються рівними.
Stéphane Chazelas відзначив випадок у коментарях, де ~і $HOMEдають різні значення: якщо ви unset HOME, то при використанні ~Bash зателефонуєте getpwuidпрочитати значення з бази даних паролів. Цей випадок виключається вашою умовою не змінювати конфігурацію $HOME, але я згадаю її тут для повноти.
/bin/shможливо, не буде bash. Я не впевнений, що shспецифікація Posix розповідає про~
~. ~не було в оболонці Томсона чи Борна (які в свій час були доступні як /bin/sh). Це не в rcйого похідних (де його використовують для чогось іншого)
bash, якщо HOMEце не встановлено, ~розширюється на домашній каталог користувача з бази даних passwd. Тож це випадок, коли він ~може не розширюватися до значення $HOME.
bashперед тим bash4 використовується для виконання підстановки при розширенні тильди (TRY HOME='/*' bash -c 'echo /*'). Тож HOME=/*; [ "$HOME" = ~ ]повернемо туди помилку.
get_current_user_info , який використовує getpwuidна всіх платформах , але Тандем .
~це буде рівнозначно$HOMEв будь-якому середовищі POSIX; але я можу помилитися.