Разница между "CD" и "CD ~"

10

Мне интересно, если один только CD отправляет меня в мою домашнюю папку, а cd ~ делает то же самое, почему тогда ~ был добавлен в первую очередь?

Это что-то особенное для BASH или они будут вести себя по-другому в другой оболочке?

Луис Альварадо
источник
2
Определенно не дубликат. Этот вопрос спрашивает о cd ~против cd $HOMEпротив cd ~not-tandu. Этот вопрос задает о cdпротив cd ~.

Ответы:

17

~Может быть использован для более чем просто. Любая команда может получить выгоду от наличия ярлыка для домашней папки. Так что нет необходимости, если вы хотите, чтобы CD в ваш дом, но как насчет ~/.config?

$ cd ~/.config

В противном случае вам придется выписать домашний путь, использовать $HOMEпеременную var или сделать две cds. Также для копирования или перемещения файлов:

$ cp ~/downloads/some-file some/path/

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

ahilsend
источник
Привет, ahilsend, на самом деле мой вопрос больше ориентирован на то, почему 2 способа. Я уже знаю об ~ использовании переменной $ HOME, но, с учетом этого, почему только «CD» также отправляет меня домой. Почему 2 пути для одной цели?
Луис Альварадо
4
@CYREX Я бы предпочел сохранить набор текста для очень распространенного случая желания перейти в домашнюю директорию.
CVn
1
Другое использование ~это сделать, cd ~user/downloadчтобы перейти в каталог загрузки пользователя.
ot--
5

В cd основном это вызов cdбез аргументов и в соответствии с cdповедением «... если dir не указан, значение переменной оболочки HOME является значением по умолчанию». (из руководства Bash ). Напротив, cd ~это когда вы передаете аргумент cdкоманде, что происходит, ~и shell выполнит расширение тильды . Что касается возврата в домашний каталог пользователя - нет никакой разницы. В любом случае HOMEпеременная окружения будет запрошена:

$ env 'HOME=/usr' bash -c 'cd;pwd; cd ~;pwd'                                      
/usr
/usr

По сути, это также не имеет никакого отличия от cd $HOME. Однако, в то время как cdбудет делать одно-единственное, тильду можно использовать для выполнения других расширений, например ~+для текущего рабочего каталога.

Однако, что интересно, мы можем unset HOMEсломаться, cdно ~все равно будем работать:

$ bash -c 'cd /usr;unset HOME;cd;pwd;cd ~;pwd'                                    
bash: line 0: cd: HOME not set
/usr
/home/xieerqi

Почему ? Опять же, ответьте в руководстве:

Если HOME не задан, вместо него подставляется домашний каталог пользователя, выполняющего оболочку. В противном случае префикс тильды заменяется домашним каталогом, связанным с указанным именем входа.

Обратите внимание, что сброс не отличается от создания пустой переменной HOME=и имеет эффект. Документация конкретно говорит о сбрасывании переменной. Создание переменной равной пустой строке имеет эффект, противоположный тому, что мы ожидали:

bash-4.3$ env 'HOME=' bash -c 'cd /usr;set|grep "^HOME"; stat -c "%F" ~;cd;pwd'
HOME=
stat: cannot stat '': No such file or directory
/usr

Здесь вы можете увидеть, что создание HOMEпустой строки нарушает как тильду, так и cdповедение.


Тильда и $HOMEесть какая то разница и другая причина существования. $HOMEявляется переменной оболочки, которая также случайно оказывается одной из переменных среды - и которая доступна для всех программ; в C вы будете использовать environ()для доступа к этому. В отличие от этого, tildeэто специфичный для оболочки синтаксис, который выполняет раскрытие тильды, хотя вы можете использовать wordexp()функцию для выполнения подобного оболочке расширения ( ссылки ) также в Си.

Причина, по которой ~представитель представляет HOMEответ в этом вопросе : однажды персонаж тильды поделился тем же ключом с HOMEтерминалом Lear-Siegler ADM-3A. HOMEнапротив, переменная окружения имела чисто символическое значение и не имела физических представлений.

Кроме того, тот факт, что HOMEэто переменная окружения, позволяет нам ее сбрасывать, поскольку мы не можем установить ~что-то еще с помощью простых средств.

# cd ~ will still work, because ~ is blank, so it's same as just cd
$ bash -c 'unset HOME; echo $HOME; cd ~;pwd'                           

/home/xieerqi
$ env 'HOME=' bash -c 'echo $HOME; cd ~;pwd'                                

/home/xieerqi

Обратите внимание на пустую строку, где сначала echoвыводится неустановленная переменная, и тот факт, что. В отличие от этого, мы не можем делать такие вещи для тильды:

$ bash -c '~=; cd ~;pwd'                                                    
bash: ~=: command not found
/home/xieerqi
$ bash -c '~=$'\0'; cd ~;pwd'                                               
bash: ~=bash: command not found
/home/xieerqi
$ bash -c 'unset ~; cd ~;pwd'                                               
bash: line 0: unset: `/home/xieerqi': not a valid identifier
/home/xieerqi

Однако изменение HOMEвлияет на ~:

$ env 'HOME=' bash -c 'echo $HOME; stat ~;'                                 

stat: cannot stat '': No such file or directory

Кроме того, поскольку он ~также работает как символ расширения, мы можем сделать что-то вроде этого, чтобы показать текущий рабочий каталог:

$ bash -c 'cd /etc/;stat -c "%n" ~+'                                        
/etc

Принимая во внимание, что если мы хотим сделать это через переменные окружения, нам нужно PWDи HOMEостается тем же самым, или если вы делаете что-то подобное echo $HOME+- это просто конкатенация строк / переменных. Но опять же, ~+берет информацию из переменных среды:

$ bash -c 'cd /etc/;PWD="/usr";stat -c "%n" ~+'                             
/usr

Примечание : ~+и ~-расширения работы в ksh, но не в dash.


Чтобы ответить на некоторые ваши конкретные вопросы:

Это что-то особенное для BASH или они будут вести себя по-другому в другой оболочке?

Нет, это должно быть последовательное поведение. ksh, dashи csh- все ведут себя одинаково с cdили cd ~.

почему ~ был добавлен в первую очередь тогда?

Я бы сказал, удобство и исторические причины, как объяснено в связанном ответе о тильде. В конце концов, он вырос не только для расширения домашнего каталога.

Сергей Колодяжный
источник
0

Независимо от того, находитесь ли вы на нескольких уровнях папок выше или ниже $HOME, команды cdи cd ~делают одно и то же и не отличаются - он отправит вас обратно в ваш каталог HOME.

ОДНАКО: Когда вы находитесь на 1 или более уровней папок выше HOME и хотите перейти ПРЯМО в подкаталог на 1 или более уровней папок ниже $HOME, функция tilde ( ~) оказывается полезной благодаря сохранению нажатий клавиш при замене текста, необходимого для ссылки чтобы $HOMEпри вводе cdкоманды. Например;

/$ cd    # (or cd ~)
~$ pwd
/home/foo
~$ dir
bar bar2 bar3
~$ cd ..
/$ cd ..
/$ pwd
/
/$ cd /bar3
bash: cd: /bar3: no such file or directory
/$ cd ~/bar3    # (instead of "cd /home/foo/bar3")
~/bar3$ pwd
/home/foo/bar3
П Александр
источник
0

~ обозначает / home / username location, поэтому вы экономите время при наборе текста. Например, cd / home / username / Downloads такой же, как cd ~ / Downloads, но меньше печатает. Обе команды делают то же самое, измените рабочий каталог на это место.

Йонут
источник
На самом деле, нет. Например root, домашний каталог обычно находится снаружи/home
Дмитрий Григорьев