Різниця між "cd -" і "cd ~ -"


56

Команда Bash

cd - 

друкує раніше використаний каталог та змінює його.

З іншого боку, команда Bash

cd ~-

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

Це єдина різниця? Який випадок використання кожної з команд?


3
Я рекомендую вам не використовувати жоден із цих хитромудрих речей. Це ваш мозок далі cd ~-.
ДепресіяДаніель

10
@DepressionDaniel, навіть якщо ви не плануєте використовувати хитрі речі, все-таки корисно зрозуміти, що відбувається за лаштунками - розуміння кутових випадків може вивести вас з діри пізніше при спробі налагодити щось інше.
черговий день

Відповіді:


81

Тут грають дві речі. По-перше, -поодинці розширено до попереднього каталогу. Це пояснюється в cdрозділі man bash(моє наголос):

Аргумент -перетворюється в $ OLDPWD перед спробою зміни каталогу. Якщо використовується не порожнє ім'я каталогу від CDPATH або якщо -це перший аргумент, і зміна каталогу успішно, абсолютна назва нового робочого каталогу записується на стандартний вихід. Повернене значення відповідає дійсності, якщо каталог було успішно змінено; помилково інакше.

Таким чином, звичайний cd -переведе вас до попереднього каталогу та надрукує ім'я каталогу. Інша команда задокументована в розділі "Розширення Тільди":

Якщо префікс tilde є a ~+, значення змінної оболонки PWD замінює префікс tilde. Якщо префікс тильди є 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 -це, ви просто надрукуєте -. Це ~-частина функціоналу розширення tilde і поводиться аналогічно змінній. Ось чому можна echo ~-і отримати щось значуще. Ви також можете використовувати його, cd ~-але ви можете так само добре використовувати його в будь-якій іншій команді. Наприклад, cp ~-/* .що було б рівнозначноcp "$OLDPWD"/* .


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

1
@terdon сьогодні я дізнався.
sitilge

Словом ... cd ~-/..працює, cd -/..чи не так!
Рей Фосс

13

~-підлягає розширенню tilde (див. 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. Це пізніше розширення в та .

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.