Разница между «CD -» и «CD ~ -»


56

Команда Bash

cd - 

печатает ранее использованный каталог и вносит в него изменения.

С другой стороны, команда Bash

cd ~-

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

Это единственная разница? Какой вариант использования для каждой из команд?


3
Я рекомендую вам не использовать эти хитрые вещи. Это твой мозг включен cd ~-.
— ДепрессияДаниэль

10
@DepressedDaniel, даже если вы (не планируете) использовать хитрые вещи, все равно полезно понимать, что происходит за кулисами - понимание угловых случаев может позже вытащить вас из дыры при попытке отладить что-то другое.
— anotherdave

Ответы:


81

Здесь есть две вещи. Во-первых, -один расширяется до вашего предыдущего каталога. Это объясняется в cdразделе man bash(выделение мое):

Аргумент аргумента -преобразуется в $ OLDPWD до попытки изменения каталога. Если используется непустое имя каталога из CDPATH, или если -это первый аргумент, и смена каталога прошла успешно, абсолютный путь нового рабочего каталога записывается в стандартный вывод. Возвращаемое значение равно true, если каталог был успешно изменен; ложь в противном случае.

Таким образом, простой cd -переместит вас обратно в ваш предыдущий каталог и выведет его имя. Другая команда описана в разделе «Расширение тильды»:

Если префикс тильды равен a ~+, значение переменной оболочки PWD заменяет префикс тильды. Если префикс тильды равен a ~-, подставляется значение переменной оболочки OLDPWD, если оно установлено. Если символы, следующие за тильдой в префиксе тильды, состоят из числа N, необязательно с префиксом a +или a -, префикс тильды заменяется соответствующим элементом из стека каталогов, как это будет показано встроенной командой dirs, вызываемой с помощью префикс тильды в качестве аргумента. Если символы, следующие за тильдой в префиксе тильды, состоят из числа без начального +или -, +предполагается.

Это может быть легче понять на примере:

$ pwd
/home/terdon
$ cd ~/foo
$ pwd
/home/terdon/foo
$ cd /etc
$ pwd
/etc
$ echo ~        ## prints $HOME
/home/terdon
$ echo ~+       ## prints $PWD
/etc
$ echo ~-       ## prints $OLDPWD
/home/terdon/foo

Так что, в общем, -означает «предыдущий каталог». Вот почему cd -само по себе вернет вас туда, где вы были.

Основное отличие заключается в том, что cd -характерно для cdвстроенного. Если вы попытаетесь echo -это просто напечатать -. ~-Является частью функциональности расширения тильды и ведет себя аналогично переменный. Вот почему вы можете echo ~-и получить что-то значимое. Вы также можете использовать его, cd ~-но вы также можете использовать его в любой другой команде. Например, cp ~-/* .который будет эквивалентенcp "$OLDPWD"/* .


1
set -xдля распечатки расширенной команды перед ее выполнением может быть полезно проиллюстрировать разницу (или может быть просто нечитабельно шумно, когда вы не делаете это самостоятельно по одному шагу за раз).
— Питер Кордес

1
@terdon сегодня я узнал.
— sitilge

Короче ... cd ~-/..работает, cd -/..нет!
— Рэй Фосс

13

~-подлежит расширению тильды (см. man bash), так что cdнепосредственно видно предыдущее имя каталога. -не раскрывается оболочкой, cdвидит его напрямую и ведет себя так, как задокументировано:

Аргумент - эквивалентен $ OLDPWD. Если используется непустое имя каталога из CDPATH, или если - первый аргумент, и изменение каталога прошло успешно, абсолютный путь нового рабочего каталога записывается в стандартный вывод.


4

TL; DR: cd -встроен cd, ~-является более поздним расширением ~[name], не относится к cd.

POSIX.1-2008 Shell & Utilities определяет cd -как особый случай, специфичный для cdкоманды :

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

cd "$OLDPWD" && pwd

который изменяется на предыдущий рабочий каталог, а затем записывает его имя.

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

Вышеупомянутый стандарт POSIX.1-2008 Shell & Utilities также содержит подробное объяснение расширения Tilde . Формулировка очень специфична и допускает ~-неопределенное поведение в рамках стандарта, где ~[name]ссылается на $HOMEто, [name]является ли пустая строка, или на домашний каталог пользователя, nameесли nameэто действительное имя пользователя.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.