Czy cd. użyć?


102

Jeden z samouczków, które śledziłem krótko, stwierdził, że cd .nie ma sensu. Podczas próby odtworzenia problemu pokazanego przez OP w rekursji łącza symbolicznego - co powoduje, że „resetuje się”? , Próbowałem również cd ., który wykazał ten sam opisany efekt OP ( $PWDzmienna rosnąca ), z którym można się przeciwdziałać cd -P.

Zastanawiam się, czy jest jakiś przypadek, w którym ktoś chciałby skorzystać cd . ?


20
Mam niestandardowy plik .zshrc, który uruchamia różne kontrole katalogu podczas przełączania katalogu, na przykład jednym z nich jest automatyczne włączanie / wyłączanie pasującego virtualenv podczas przenoszenia katalogów. Czasami mogę uruchomić nową powłokę lub cokolwiek innego, a te kontrole nie są uruchamiane, i zwykle używam cd .do uruchamiania tych kontroli, ponieważ są one krótkie i proste. Chociaż myślę, że chciałeś, aby pytanie dotyczyło środowiska waniliowego.
Lie Ryan,

29
Oprócz (oczywistego) wpływu na $PWD, cd .zmienia $OLDPWDsię również bieżący katalog. Nie mam (obecnie) pojęcia, dlaczego to może być przydatne, ale ze względu na kompletność…
Andreas Wiese

5
Nie sądzę, żebym kiedykolwiek potrzebował cd ., chociaż widzę poniższe odpowiedzi, może w przyszłości, ale czasami korzystałem z niego, pushd .gdy chciałem móc popdpóźniej wrócić do tego katalogu. np. po uruchomieniu skryptu kompilacji, który to robi configure, cd output...a makekiedy to zrobi, chcę wrócić do oryginalnego katalogu. Zamiast utrzymywać własną kopię pliku skryptowego, który różni się od tego, czego wszyscy inni oczekują, po prostu uruchamiam go jako pushd .; ./BuildScriptName.sh; popd, a to daje mi również swobodę popdniekiedy, a potem popdpóźniej.
3D1T0R

5
Nie wspominając oczywiście, że „.” i „..” nie są zaimplementowane w samym poleceniu cd, więc nikt nie postanowił wprowadzić tej konkretnej funkcji, to tylko kombinacja rzeczy, które nie służą żadnemu celowi.
David S

1
@ruakh Nie, programy zewnętrzne nie powinny wpływać na środowisko wykonywania powłoki. Dotyczy to głównie zgodności z POSIX, która wymaga, aby niektóre narzędzia istniały poza powłoką i oceniały status wyjścia poleceń zewnętrznych. Możesz przeczytać o celu /bin/cdtutaj unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

Odpowiedzi:


158

Myślę, że to przesadza z problemem. cd .może nie być czymś, co można by ręcznie uruchomić w zwykłym toku, ale na pewno jest to coś, co może pojawić się przy wykonywaniu programowym (pomyśl o każdej sytuacji, w której możesz cdprzejść do katalogu zawierającego plik, którego ścieżkę podaje użytkownik ). Dlatego nie musi mieć określonego zastosowania: dopóki spełnia normalną semantykę cd <some-path>, jest przydatny.


12
Uzgodnione, .należy traktować jako poprawną ścieżkę określoną przez cdskładnię.
Sergiy Kolodyazhnyy

18
Możesz dodać następujący przykład: Pętle takie jak while IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d). W trakcie jego działania znajdź produkuje .jako ścieżkę, aby polecenie cd "$Dir"rozwijało się do cd .. Tak więc w skryptach jest to całkowicie przydatne.
rexkogitans

5
Na przykład skrypt faktycznie działa cd ${path_to_directory}, ale w pewnym momencie okazuje się, że katalog jest katalogiem bieżącym, path_to_directory = .więc cd .na wszelki wypadek musiałbyś pracować.
Demis

4
Innymi słowy, jego użyteczność polega na tym, że sprawia, że ​​dodatkowy kod ( ifkontrole i elseklauzule, wszelkiego rodzaju specjalna obudowa) nie jest potrzebny.
jpmc26

2
Jest to użyteczne w tym sensie, że x + 0 lub x * 1 są przydatne - konkretna operacja sama w sobie nie jest przydatna, ale oznacza, że ​​możesz obsłużyć 0 i 1 tak samo jak każdą inną wartość, bez konieczności traktowania ich jako specjalny przypadek.
user32929

127

Ścieżka do katalogu mogła ulec zmianie od czasu wykonania ostatniego polecenia, a bez cd .powłoki bash i ksh93 powłoki będą polegać na logicznym katalogu roboczym opisanym w poście, do którego link znajduje się w pytaniu, więc wywołanie, cd .które powoduje problem z powłoką , wywołuje getcwd()syscall aktualna ścieżka jest nadal aktualna.

Kroki do odtworzenia w bash:

  1. W kwestii karty terminalu mkdir ./dir_no_1; cd ./dir_no_1
  2. W innym wydaniu karty terminalu mv dir_no_1 dir_no_2
  3. W pierwszym wydaniu karty terminalu echo $PWDi pwd. Zauważ, że nazwa katalogu została zmieniona zewnętrznie; środowisko powłoki nie zostało zaktualizowane.
  4. Kwestia cd .; pwd; echo $PWD. Zauważ, że wartość została zaktualizowana.

Jednak ksh93 nie aktualizuje informacji o środowisku, więc cd .w ksh93 może być w rzeczywistości bezużyteczny. W /bin/dashsystemach Ubuntu i innych systemach opartych na Debianie cd .zwraca dash: 3: cd: can't cd to .błąd, jednak cd -P .działa (w przeciwieństwie do ksh93).


22
Dobrze wiedzieć: dodam to do mojej listy bezużytecznych informacji. ^^)
jayooin

12
@jayooin Cieszę się, że mogłem przyczynić się do listy;)
Sergiy Kolodyazhnyy

8
Myślę, że możesz to zrobić mv ../dir_no_1 ../dir_no_2w tym samym terminalu / bash.
ctrl-alt-delor

3
@ ctrl-alt-delor Potwierdzony, działa :)
Sergiy Kolodyazhnyy

1
@ymbirtt W większości powłok pwdjest w rzeczywistości wbudowany, jednak wywoływanie /bin/pwdnie ma wpływu na środowisko powłoki - narzędzia zewnętrzne w ogóle nie wpływają na środowisko powłoki. Powodem /bin/cdi /bin/pwdmiędzy innymi jest zgodność z POSIX. Jest dobra dyskusja na temat zewnętrznego dysku CD z których niektóre prawdopodobnie dotyczy /bin/pwdrównież
Sergiy Kolodyazhnyy

55

Innym przykładem użycia cd .może być usunięcie katalogu, w którym aktualnie się znajdujesz, a następnie utworzenie go ponownie. Rozważ wypróbowanie następujących opcji -

  1. Utwórz katalog temp
  2. cd temp a następnie zrób ls
  3. Otwórz inny terminal i usuń, a następnie ponownie utwórz ten katalog temp
  4. Wracając z pierwszego terminalu, spróbuj zrobić ls. Spowodowałoby to błąd -ls: cannot open directory .: Stale file handle
  5. cd . a następnie wykonanie ls działa dobrze

3
To nie zawsze działa. Na przykład w desce rozdzielczej otrzymasz: cd: can't cd to .Teraz, gdy na to patrzę, jest to już wspomniane w odpowiedzi Sergiy (przenoszenie, usuwanie / odtwarzanie - zasadniczo to samo: katalog, w którym jesteś, nie jest już tym, co było w oryginale path)
Olorin

12
Często używam tego do testowania zdalnych wdrożeń. Katalog, w którym się znajduję, zostanie usunięty, a następnie ponownie utworzony przez pewną automatyzację i będę musiał wydać cd .polecenie przejścia do nowego katalogu o tej samej nazwie.
HP Williams

2
Używam cd .cały czas, gdy mam powłokę, której bieżący katalog roboczy został podłączony za pomocą sshfs, ale sesja ssh została zamknięta i ponownie otwarta.
jamesdlin

4
W takim przypadku robię „cd $ PWD”. Inne warianty mogą działać, ale ten wyraźnie wyraża intencję: wyodrębnij, co powinno być moją bieżącą ścieżką (tj. Przeczytaj zawartość PWDzmiennej środowiskowej), a następnie przejdź do hierarchii systemu plików od katalogu głównego do katalogu, który jest osiągalny przez ta ścieżka, niezależnie od tego, czy jest to faktycznie ten sam katalog, czy nie. To pasuje dokładnie do przypadku użycia w tej odpowiedzi.
Stéphane Gourichon

3
Jestem naprawdę zaskoczony, nawet zszokowany, że to cd .działa, gdy katalog został odłączony i nowy, inny katalog jest tworzony w tej samej ścieżce systemu plików. Bieżący katalog roboczy został odłączony i prawdopodobnie w ramach tego nie ma już wpisu .lub .., a nawet jeśli tak, .wpis powinien nadal wskazywać na siebie. Wygląda na to, że powłoka lub jądro wykonuje polecenie cd w oparciu o nazwę ścieżki katalogu, a nie tylko dostęp do .wpisu. Czy ktoś może potwierdzić to zachowanie?
Adrian Pronk

36

Możesz to wyczyścić $OLDPWDszybko cd ., jeśli powinien istnieć przypadek, w którym nie chcesz, aby wskazywał „interesujące”. Wpłynie to również cd -.


16

Programowo jest użyteczny jako brak możliwości. Rozważ ścieżkę podaną z zewnętrznego źródła.

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

Dzięki ścieżce takiej jak „fred.txt” katalog stanie się ., prowadząc docd .


1
Przydatne jest to, że nie zgłasza błędu, jeśli jesteś już w katalogu, do którego nawigujesz, ale nie powiedziałbym, że jest to przydatne jako brak możliwości.
Captain Man

2
@CaptainMan nie zgłasza błędu, jeśli jesteś już w katalogu, to (skutecznie) brak możliwości. dirnameKomenda generuje .gdzie konieczne, aby uniknąć łamanie kodu, który oczekuje, że będzie w stanie podzielić ścieżkę.
roaima

15

Jest to powszechne, jeśli musiałeś pracować ze złym kablem USB. Po odłączeniu urządzenia i ponownym podłączeniu oraz automatycznym podłączeniu do tego samego katalogu, musisz użyć cd .go, aby ponownie uruchomić urządzenie.


1
Czy to nie zależeć będzie od rodzaju urządzenia, sposobu dostępu, systemu plików, systemu operacyjnego i c?
gidds

Może OS. Jest mało prawdopodobne, aby system plików był istotny, dopóki jądro może znaleźć sposób odmontowania go podczas jego używania. W każdym razie polecenie ma zastosowanie w dokładnie właściwej sytuacji.
user23013

11

Pamiętaj, że „.” to właściwy sposób na określenie nazwy pliku, który jest otwarty jako bieżący katalog roboczy dowolnego procesu (w tym oczywiście procesu powłoki), i „.” jest zawsze prawidłową nazwą pliku we wszystkich katalogach, w tym w bieżącym katalogu roboczym. Nazwa .może nie być prawidłową nazwą pliku dla danej instancji procesu, jeśli powiedzmy, że bieżący katalog roboczy został usunięty (lub „źle”, np. Nieaktualny uchwyt NFS), ale jest to poprawna nazwa pliku, który na pewno istnieje w każdym prawidłowym katalogu.

. Musi więc być poprawnym argumentem dla każdego polecenia, które akceptuje nazwę katalogu, a zatem w standardowej powłoce cd .musi być poprawnym poleceniem.

To, czy cd .jest przydatne, czy nie, zależy od implementacji powłoki. Jak wspomniano, może być użyteczne, jeśli powłoka resetuje swoją wewnętrzną koncepcję pełnej nazwy ścieżki bieżącego katalogu roboczego po wywołaniu bazowego chdirwywołania systemowego, powiedzmy na przykład, czy nazwa katalogu bazowego (lub jego rodzica) została zmieniona.

Przynajmniej niektóre powłoki, które znam ( /bin/shna FreeBSD i NetBSD), zostaną przekonwertowane cd ""na cd ., co można prawdopodobnie opisać funkcję wspierającą programowe użycie w skrypcie powłoki, w którym zmienna może być użyta jako parametr (tj. Konwersja podstawienia pustej zmiennej na „ „nic nie rób”), choć historia zatwierdzeń FreeBSD mówi, że zmiana była spowodowana bezpośrednio dodaniem obsługi POSIX, aby zapobiec awarii chdir(""), której mandaty POSIX muszą zawieść.

Niektóre inne powłoki zastąpią .wszystko, co zachowały jako w pełni kwalifikowaną ścieżkę do ich bieżącego katalogu roboczego, a zatem dla nich może to pozwolić na zachowanie wymienione w odpowiedzi Sahila Agarwal'a .


4

Użyłem tego polecenia dopiero dzisiaj, kiedy zmieniłem gałąź, nad którą pracowałem w Git, z katalogu, który został najpierw utworzony w tej samej gałęzi. Rebase poszło dobrze, ale później git statuszgłosił błąd. Po tym cd .wszystkim było normalnie.

(Nawiasem mówiąc, pracowałem w MobaXterm na Windowsie. Na wypadek, gdybyś próbował to odtworzyć. Może się to nie zdarzyć na innych systemach).


Użyłem również tego polecenia w katalogach, które są odświeżane przez zautomatyzowany proces, który odsuwa stary katalog i zastępuje go nowym (tak, aby był jak najbliżej atomu). Nie jest to powszechna sytuacja, ale cd .jest dokładnie tym, czego potrzeba.


Po przeczytaniu tej doskonałej odpowiedzi Stephane Chazelas:

Teraz rozumiem, że moje powyższe przypadki użycia działają tylko dlatego, że używam bash, w którym cd .jest to równoważne z cd "$PWD". Bardzo polecam przeczytanie połączonej odpowiedzi.


1

Używam cd .do ponownego uruchomienia rzeczy, które zostały przeciążone cdza pomocą bashfunkcji.

Od mojego ~/.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

EDYCJA: Sugerowało to wcześniej Sahil .

Jest to przydatne, jeśli znajdujesz się w folderze, który został usunięty i ponownie utworzony przez inny proces. Na przykład zakładając dwie sesje terminalowe $1i $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

Nie jestem pewien, czy dokładnie gdzie (OS, SHELL, ...?) Podstawową przyczyną tego zachowania jest.


Zostało to już wspomniane w innych odpowiedziach.
Kusalananda

-8

Nie, to nie ma sensu. Ani w skryptach nic nie robi.


2
W zależności od powłoki zresetuje się $PWDi prawdopodobnie wywoła inne funkcje powłoki, jeśli użytkownik poda własną cdfunkcję lub alias w celu przeciążenia wbudowanego cd. Sprawdziłby również, czy bieżący katalog jest nadal aktualny i czy bieżące użycie ma pozwolenie na bycie tam.
Kusalananda

1) oczywiście nie mówimy o możliwych niestandardowych aliasach „cd”, ale o standardowej wersji 2) w jaki sposób może być obecne użycie, gdyby nie miało pozwolenia? Upraszczając, po prostu mówię, że w prawdziwym świecie nie ma powodu, aby używać go w mojej opinii.
Federico

1
1) Czyż nie jesteśmy? 2) Rzeczywisty świat nie jest prosty, a Unix to system operacyjny dla wielu użytkowników. Użytkownik może zmienić uprawnienia do katalogów, a jeśli skrypt lub interaktywna powłoka innego użytkownika zdarzy się, że ten katalog (lub jego podkatalog) jako katalog roboczy cd .narzeka.
Kusalananda

4
Federico, zgodnie z regulaminem strony i moimi osobistymi zasadami, powinienem głosować za odpowiedzią. Jesteś jednak nowy. Witamy! Przejrzyj inne odpowiedzi . Następnie, jeśli uważasz, że twoja odpowiedź jest nieprawidłowa, usuń ją. Podaj inne odpowiedzi na to pytanie i inne.
daveloyall

2
Zwłaszcza w skryptach czasami „nic nie robi” jest dokładnie tym, czego potrzeba.
Matthew Najmon
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.