Чи cd. є використання?


102

Один із навчальних посібників, які я дотримувався, коротко заявив, що cd .не має користі. Коли ви намагаєтесь повторити проблему, показану ОП у символічній рекурсії посилання - що робить її “скиданням”? , Я також спробував cd ., який показав той же ефект, що описаний OP (зростаюча $PWDзмінна), з якою можна протистояти cd -P.

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


20
У мене є власний .zshrc, який виконує різні перевірки каталогу під час переключення каталогу, наприклад, одна з перевірок - це автоматично активувати / деактивувати відповідні virtualenv при переміщенні каталогів. Інколи я можу запустити нову оболонку чи будь-що інше, і ці перевірки не запускаються, і я зазвичай використовую cd .для запуску цих перевірок, оскільки це коротко і просто. Хоча я думаю, що ви задумали, що питання стосується ванільного середовища.
Лежать Раян

29
Окрім (очевидного) впливу на $PWD, cd .також змінюється $OLDPWDпоточний каталог. Я (наразі) не маю поняття, чому це може бути корисним, але заради повноти…
Андреас Візе

5
Я не думаю, що мені ніколи не потрібні. cd .Хоча, бачачи відповіді нижче, я можу в майбутньому, але я іноді використовував, pushd .коли хотів popdпізніше повернутися до цього каталогу. наприклад, під час запуску сценарію збірки, який є configure, cd output...і make, і коли це буде зроблено, я хочу повернутися до початкового каталогу. Замість того, щоб підтримувати власну копію buildscript, що відрізняється від того, що всі очікують, я просто запускаю це як pushd .; ./BuildScriptName.sh; popd, і це також дає мені свободу не popdіноді, а потім popdпізніше.
3D1T0R

5
Не кажучи вже про те, що "." і ".." не реалізовані в самій команді cd, тому ніхто не ставить за мету зробити цю специфічну особливість, це лише комбінація речей, яка не відповідає реальній меті.
Девід S

1
@ruakh Ні, зовнішні програми не повинні впливати на середовище виконання оболонки. Це здебільшого для відповідності POSIX, яка вимагає, щоб деякі утиліти існували поза оболонкою, та оцінка стану виходу зовнішніх команд. Про мету ви можете прочитати /bin/cdтут unix.stackexchange.com/q/50058/85039
Сергій Колодяжний,

Відповіді:


158

Я думаю, що це переосмислення проблеми. cd .можливо, це не те, що вручну запускалося в звичайному процесі, але, безумовно, це те, що може придумати програмне виконання (подумайте про будь-яку ситуацію, де ви могли б потрапити до cdкаталогу, що містить файл, шлях якого надає користувач ). Отже, воно не повинно мати певного використання: доки воно відповідає звичайній семантиці cd <some-path>, це корисно.


12
Погоджено, .слід трактувати як дійсний шлях, визначений cdсинтаксисом просто добре.
Сергій Колодяжний

18
Можна додати наступний приклад: Петлі, як і в той час, як IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d). Під час його пошуку знайдіть продукцію .як шлях, так що команда cd "$Dir"розширюється на cd .. Тож у сценаріях це цілком корисно.
rexkogitans

5
Наприклад, сценарій насправді працює cd ${path_to_directory}, але в якийсь момент виявляється, що каталог є поточним каталогом, і path_to_directory = .тому вам потрібно cd .буде працювати на всякий випадок.
Деміс

4
Іншими словами, його корисність полягає в тому, що він робить зайвий код ( ifперевірки та elseпункти, будь-який вид спеціального корпусу) непотрібним.
jpmc26

2
Тож корисно в тому сенсі, що x + 0 або x * 1 є корисними - конкретна операція сама по собі не є корисною, але це означає, що ви можете обробити 0 і 1 так само, як і будь-яке інше значення, без необхідності ставитися до них як особливий випадок.
користувач32929

127

Шлях до каталогу міг змінитись з часу останньої команди команди, і без cd .оболонок bash та ksh93 буде покладатися на логічний робочий каталог, описаний у публікації, пов’язаній у запитанні, тому виклик, cd .який робить оболонку, видає getcwd()syscall, забезпечить ваш поточний шлях досі діє.

Кроки до відтворення в баші:

  1. У випуску вкладки терміналу mkdir ./dir_no_1; cd ./dir_no_1
  2. У іншому випуску терміналу mv dir_no_1 dir_no_2
  3. У першій випуску вкладки терміналу echo $PWDі pwd. Зауважте, що каталог було перейменовано зовні; середовище оболонки не оновлено.
  4. Випуск cd .; pwd; echo $PWD. Зверніть увагу, що значення було оновлено.

ksh93, однак, не оновлює інформацію про навколишнє середовище, тому cd .в ksh93 насправді може бути марним. У /bin/dashUbuntu та інших системах на базі Debian cd .повертає dash: 3: cd: can't cd to .помилка, проте cd -P .працює (на відміну від ksh93).


22
Добре знати: я додам це до свого списку марної інформації. ^^)
jayooin

12
@jayooin Радий, що я можу внести свій внесок у список;)
Сергій Колодяжний,

8
Я думаю, ви можете зробити mv ../dir_no_1 ../dir_no_2в одному терміналі / баш.
ctrl-alt-delor

3
@ ctrl-alt-delor Підтверджено, працює :)
Сергій Колодяжний,

1
@ymbirtt У більшості оболонок pwdнасправді є вбудованим, однак виклик /bin/pwdне впливає на середовище оболонки - зовнішні утиліти взагалі не впливають на середовище оболонки. Причина , чому /bin/cdі /bin/pwdіснує для POSIX відповідність, між іншим. Там дуже хороша дискусія про зовнішньому диску , деякі з яких , ймовірно , відноситься і до /bin/pwdа
Сергій Kolodyazhnyy

55

Іншим випадком використання cd .буде те, коли каталог, у якому ви зараз перебуваєте, був видалений, а потім знову створений. Спробуйте виконати наступне -

  1. Створіть каталог temp
  2. cd temp а потім зробіть ls
  3. Відкрийте інший термінал і видаліть, а потім відтворіть цей каталог temp
  4. Повернувшись з першого терміналу, спробуйте зробити ls. Це призведе до помилки -ls: cannot open directory .: Stale file handle
  5. cd . а потім робити ls працює чудово

3
Це не завжди працює. Наприклад, тире ви отримаєте: cd: can't cd to .Тепер, коли я дивлюся на це, це вже згадується у відповіді Сергія (переміщення, видалення / відтворення - по суті те саме: каталог, в якому ви перебуваєте, вже не є тим, що було в оригіналі шлях)
Олорін

12
Я використовую це багато для тестування віддалених пристроїв. Каталог, в якому я перебуваю, буде видалений, після чого відтворений деякою автоматизацією, і мені потрібно буде видати, cd .щоб перейти до нового каталогу з тим самим іменем.
HP Williams

2
Я використовую cd .весь час, коли у мене є оболонка, чий поточний робочий каталог був змонтований за допомогою sshfs, але сеанс ssh закритий та відкритий.
jamesdlin

4
У такому випадку я роблю "cd $ PWD". Інші варіанти можуть працювати, але цей чітко виражає наміри: витягніть те, що повинно бути моїм поточним шляхом (тобто прочитати вміст PWDзмінної середовища), а потім перейдіть по ієрархії файлової системи від кореня донизу до каталогу, до якого, можливо, можна дістатися через цей шлях, будь то насправді той самий каталог чи ні. Це точно відповідає випадку використання в цій відповіді.
Стефан Гурішон

3
Я дуже здивований, навіть шокований, що це cd .працює, коли каталог від’єднано, і новий і той же каталог створюється на тому ж шляху файлової системи. Поточний робочий каталог був від’єднаний, і, мабуть, як частина цього, він більше не має .або ..запису, і навіть якщо це було, .запис повинен продовжувати вказувати на себе. Схоже, оболонка або ядро ​​виконує команду cd, грунтуючись на тому, яке ім'я контуру каталогу було, а не просто отримувати доступ до .запису. Чи може хтось підтвердити таку поведінку?
Адріан Пронк

36

Ви можете $OLDPWDшвидко зрозуміти cd ., якщо має бути випадок, коли ви не хочете, щоб він десь вказував на "цікавий". Це також вплине cd -.


16

Програмно це корисно як не-оп. Розглянемо шлях, наданий із зовнішнього вводу.

read -p "Path to file: " p
dirn=$(dirname "$p")
file=$(basename "$p")
echo "dirn=$dirn, file=$file"
cd "$dirn"
ls -ld "$file"

З таким шляхом, як "fred.txt" каталог стане ., ведучим доcd .


1
Корисно, що він не видає помилки, якщо ви вже знаходитесь в каталозі, до якого ви переходите, але я б не сказав, що це корисно як неоператор.
Людина капітана

2
@CaptainMan не видає помилку, якщо ви вже знаходитесь в каталозі, є (фактично) неоперативним. dirnameКоманда генерує , .де це необхідно , щоб уникнути порушення коду , який очікує , щоб мати можливість розділити шлях.
roaima

15

Це звичайно, якщо вам довелося працювати з поганим USB-кабелем. Після того, як пристрій знову відключиться та підключиться до автоматичного каталогу до того самого каталогу, вам доведеться використовувати його, cd .щоб знову працювати.


1
Чи не це залежатиме від типу пристрою, способу доступу до нього, його файлової системи, ОС та c?
gidds

ОС, можливо. Навряд чи файлова система є актуальною, доки ядро ​​може знайти спосіб її відключення під час її використання. У будь-якому випадку команда має своє використання в абсолютно правильній ситуації.
user23013

11

Зауважте, що "." це правильний спосіб вказати ім’я файлу, який відкрито як поточний робочий каталог будь-якого процесу (включаючи процес оболонки, звичайно), та ". завжди є дійсним іменем файлу в будь-якому каталозі, включаючи поточну робочу директорію. Ім'я .може не бути дійсним іменем для файлу для певного примірника процесу, якщо, скажімо, базовий поточний робочий каталог було видалено (або пішло "погано", наприклад, застаріла ручка NFS), але це дійсне ім'я файлу, який гарантовано існує у кожному дійсному каталозі.

Таким чином, . повинен бути дійсним аргументом для будь-якої команди, яка приймає ім'я каталогу, і тому в стандартній оболонці cd .повинна бути дійсна команда.

Є чи cd .це корисно чи ні , залежить від реалізації оболонки. Як було зазначено, це може бути корисним, якщо оболонка скидає внутрішнє уявлення про повне ім'я поточного робочого каталогу після виклику базового chdirсистемного виклику, скажімо, наприклад, якщо базовий каталог (або якийсь його батьків) був перейменований.

Принаймні деякі оболонки, які я знаю ( /bin/shна FreeBSD і NetBSD), перетворяться cd ""в cd .які, можливо, можна описати функцію підтримки програмного використання в сценарії оболонки, де змінна може бути використана як параметр (тобто перетворення порожньої заміни змінної в " нічого не робити ", хоча історія фіксацій FreeBSD говорить, що зміни відбулися безпосередньо завдяки додаванню підтримки POSIX для запобігання збою, від chdir("")якого POSIX мандати повинні виходити з ладу.

Деякі інші оболонки замінять те, .що вони зберігали як повністю кваліфіковану назву шляху до їх поточного робочого каталогу, і, таким чином, для них це може спричинити поведінку, згадану у відповіді Сахіла Агарваля .


4

Цю команду я використав саме сьогодні, коли я відновив гілку, над якою працював у Git, із каталогу, який був створений в цій же гілці. Ребаза пройшла добре, але згодом git statusприпустила помилку. Адже cd .все було нормально.

(Я, до речі, працював у MobaXterm у Windows. На всякий випадок, якщо ви намагаєтесь відтворити це. Це може не статися в інших системах.)


Я також використовував цю команду в каталогах, які оновлюються автоматизованим процесом, який відсуває старий каталог і замінює його новим (так він максимально наближений до атомного). Не звичайна ситуація, але cd .саме те, що потрібно.


Прочитавши цю чудову відповідь від Стефана Шазеласа:

Тепер я розумію, що мої випадки використання вище працюють лише тому, що я використовую bash, в якому cd .еквівалентно cd "$PWD". Я настійно рекомендую прочитати пов'язану відповідь.


1

Я використовую cd .для повторного перевантаження матеріалів, якими я перевантажений cdчерез bashфункцію.

Від мого ~/.bashrc:

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}

0

EDIT: Це вже було запропоновано Сахілом .

Це корисно, якщо ви знаходитесь у папці, яку видалили та відтворили іншим процесом. Наприклад, якщо припустити два термінальні сеанси $1та $2:

$1 mkdir d
$1 cd d
$1 touch f

$2 rm -rf /path/to/d # delete the folder where $1 is in ...
$2 mkdir /path/to/d # ... and recreate it

$1 touch g # cannot create file g because current dir doesn't exist anymore
touch: cannot touch ‘g’: Stale file handle
$1 cd . # go to the newly created dir (same path)
$1 touch g # works fine now

Я не впевнений, чи саме там (OS, SHELL, ...?) Першопричина такої поведінки.


Про це вже згадували інші відповіді.
Kusalananda

-8

Ні, це не має сенсу. Ні в сценаріях, це просто нічого не робить.


2
Залежно від оболонки, вона буде скинута $PWDі, можливо, викликає інші функції оболонки, якщо користувач надав власну cdфункцію або псевдонім для перевантаження вбудованої cd. Він також перевірить, що поточний каталог все ще дійсний і що поточне використання має дозвіл на його перебування.
Kusalananda

1) звичайно, ми не говоримо про можливі власні псевдоніми "cd", але про стандартну збірку 2) як може бути поточне використання, якщо воно не має дозволу? Щоб зробити це просто, я просто кажу, що в реальному світі немає причин використовувати його на мою думку.
Федеріко

1
1) Чи не так? 2) Реальний світ не простий, а Unix - це багатокористувацька операційна система. Користувач може змінювати дозволи на каталоги, і якщо у скрипта або інтерактивної оболонки іншого користувача, що цей каталог (або його підкаталог) є його робочим каталогом, cd .скаржиться.
Kusalananda

4
Федеріко, згідно з правилами сайту та моїми особистими правилами, я повинен спростувати вашу відповідь. Однак ви новачок. Ласкаво просимо! Перегляньте деякі інші відповіді . Після цього, якщо ви вважаєте, що ваша відповідь неправильна, видаліть її. Будь ласка, даючи інші відповіді на це питання та інші.
daveloyall

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