Fa cd. avere uso?


102

Uno dei tutorial che ho seguito brevemente ha affermato che cd .non serve a niente. Quando si tenta di replicare il problema mostrato dall'OP nella ricorsione del collegamento simbolico, cosa lo rende "ripristinato"? , Ho anche provato cd ., che ha mostrato lo stesso effetto descritto da OP ( $PWDvariabile crescente ), che può essere contrastato cd -P.

Questo mi fa meravigliare, c'è un caso in cui uno vorrebbe davvero usare cd . ?


20
Ho un .zshrc personalizzato che esegue vari controlli sulla directory quando si cambia directory, ad esempio uno dei controlli è quello di attivare / disattivare automaticamente un virtualenv corrispondente quando si spostano le directory. Di tanto in tanto, potrei avviare una nuova shell o altro, e quei controlli non vengono eseguiti, e di solito lo uso cd .per attivare quei controlli perché è breve e semplice. Anche se penso che tu abbia pensato che la domanda fosse per un ambiente alla vaniglia.
Sdraiati Ryan il

29
Oltre all'effetto (evidente) su $PWD, passa cd .anche $OLDPWDalla directory corrente. Non ho (attualmente) idea del perché questo possa essere utile, ma per completezza ...
Andreas Wiese

5
Non credo di averne mai avuto bisogno cd ., anche se vedendo le risposte di seguito, potrei in futuro, ma a volte pushd .ho usato quando volevo poter popdtornare in questa directory in seguito. ad esempio quando si esegue uno script di build che fa configure, cd output...e make, e quando è fatto io voglio tornare alla directory originale. Invece di mantenere la mia copia del buildscript diversa da quella che tutti si aspettano, la eseguo semplicemente pushd .; ./BuildScriptName.sh; popde questo mi dà anche la libertà di non farlo popdqualche volta, e poi popdpiù tardi.
3D1T0R

5
Per non parlare, ovviamente, che "." e '..' non sono implementati nel comando cd stesso, quindi nessuno ha deciso di creare quella caratteristica specifica, è solo una combinazione di cose che non ha alcuno scopo reale.
David S,

1
@ruakh No, i programmi esterni non dovrebbero influire sull'ambiente di esecuzione della shell. È principalmente per la conformità POSIX che richiede l'esistenza di alcune utility al di fuori della shell e la valutazione dello stato di uscita dei comandi esterni. Puoi leggere lo scopo di /bin/cdqui unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

Risposte:


158

Penso che questo stia ripensando il problema. cd .potrebbe non essere qualcosa che si potrebbe eseguire manualmente nel normale corso delle cose, ma è sicuramente qualcosa che può emergere nell'esecuzione programmatica (si pensi a qualsiasi situazione in cui si potrebbe cdraggiungere la directory contenente un file, il cui percorso è fornito dall'utente ). Pertanto, non deve avere un uso specifico: purché soddisfi la solita semantica di cd <some-path>, è utile.


12
D'accordo, .dovrebbe essere trattato come un percorso valido specificato dalla cdsintassi bene.
Sergiy Kolodyazhnyy il

18
È possibile aggiungere il seguente esempio: loop come while IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d). Durante il suo percorso, find produce .come percorso, in modo che il comando si cd "$Dir"espanda a cd .. Quindi, negli script, è perfettamente utile.
rexkogitans,

5
Ad esempio, uno script viene effettivamente eseguito cd ${path_to_directory}, ma a un certo punto si scopre che la directory è la directory corrente, path_to_directory = .quindi dovresti cd .lavorare nel caso.
Demis

4
In altre parole, la sua utilità sta nel fatto che rende superfluo il codice aggiuntivo ( ifcontrolli e elseclausole, qualsiasi tipo di involucro speciale).
jpmc26,

2
Quindi è utile nel senso che x + 0 o x * 1 sono utili - l'operazione specifica non è utile di per sé, ma significa che puoi gestire 0 e 1 come qualsiasi altro valore, senza doverli trattare come un caso speciale.
user32929,

127

Il percorso della directory potrebbe essere cambiato dall'ultimo comando eseguito, e senza cd .le shell bash e ksh93 si affiderà alla directory di lavoro logica descritta nel post collegato nella domanda, quindi chiamando ciò cd .che causa il problema della shell, getcwd()syscall assicurerà che il percorso corrente è ancora valido.

I passaggi per riprodurre in bash:

  1. In un problema con la scheda terminale mkdir ./dir_no_1; cd ./dir_no_1
  2. In un diverso problema con la scheda terminale mv dir_no_1 dir_no_2
  3. Nel primo problema con la scheda del terminale echo $PWDe pwd. Si noti che la directory è stata rinominata esternamente; l'ambiente della shell non è stato aggiornato.
  4. Problema cd .; pwd; echo $PWD. Si noti che il valore è stato aggiornato.

ksh93, tuttavia, non aggiorna le informazioni sull'ambiente, quindi cd .in ksh93 potrebbe in effetti essere inutile. In /bin/dashsu Ubuntu e altri sistemi basati su Debian, cd .restituisce dash: 3: cd: can't cd to .errore, tuttavia cd -P .funziona (a differenza di ksh93).


22
Buono a sapersi: lo aggiungerò al mio elenco di informazioni inutili. ^^)
jayooin

12
@jayooin Sono contento di poter contribuire all'elenco;)
Sergiy Kolodyazhnyy il

8
Penso che tu possa fare mv ../dir_no_1 ../dir_no_2nello stesso terminale / bash.
ctrl-alt-delor

3
@ ctrl-alt-delor Confermato, funziona :)
Sergiy Kolodyazhnyy il

1
@ymbirtt Nella maggior parte delle shell, pwdinfatti , è integrato, tuttavia invocare /bin/pwdnon ha alcun effetto sull'ambiente della shell - le utility esterne in generale non influiscono sull'ambiente della shell. Il motivo per cui esiste /bin/cded /bin/pwdè per la conformità POSIX, tra le altre cose. C'è una buona discussione su cd esterni alcuni dei quali probabilmente si applicano /bin/pwdanche a
Sergiy Kolodyazhnyy il

55

Un altro caso d'uso cd .potrebbe essere quando la directory in cui ci si trova è stata eliminata e quindi creata di nuovo. Valuta di provare quanto segue:

  1. Crea una directory temp
  2. cd temp e poi fare un ls
  3. Apri un altro terminale ed elimina, quindi ricrea quella directory temp
  4. Di ritorno dal primo terminale, prova a fare un ls. Ciò comporterebbe un errore -ls: cannot open directory .: Stale file handle
  5. cd . e poi fare un lavoro funziona bene

3
Questo non funziona sempre. Nel trattino, per esempio, otterrai: cd: can't cd to .Ora che lo guardo, questo è già menzionato nella risposta di Sergiy (spostare, eliminare / ricreare - essenzialmente lo stesso: la directory in cui ti trovi non è più quella che era nell'originale percorso)
Olorin il

12
Lo uso molto testando distribuzioni remote. La directory in cui mi trovo verrà eliminata, quindi ricreata da un po 'di automazione e dovrò rilasciarla cd .per passare alla nuova directory con lo stesso nome.
HP Williams,

2
Uso cd .tutto il tempo quando ho una shell la cui directory di lavoro corrente è stata montata con sshfs ma la sessione ssh è stata chiusa e riaperta.
Jamesdlin il

4
In tal caso, faccio "cd $ PWD". Altre varianti potrebbero funzionare, ma questa esprime chiaramente l'intento: estrai quello che dovrebbe essere il mio percorso attuale (cioè leggi il contenuto della PWDvariabile d' ambiente), quindi cammina la gerarchia del filesystem dalla radice, fino a una directory che è raggiungibile tramite quel percorso, sia che si tratti effettivamente della stessa directory o meno. Questo si adatta esattamente al caso d'uso in questa risposta.
Stéphane Gourichon,

3
Sono davvero sorpreso, persino scioccato, che cd .funzioni quando la directory è stata scollegata e una nuova directory diversa viene creata nello stesso percorso del file system. L'attuale directory di lavoro è stata scollegata e presumibilmente come parte di essa, non ha più un .o una ..voce, e anche se lo fosse, la .voce dovrebbe continuare a puntare a se stessa. Sembra che la shell o il kernel stia eseguendo il comando cd in base al nome del percorso della directory piuttosto che semplicemente accedendo alla .voce. Qualcuno può confermare quel comportamento?
Adrian Pronk, il

36

Puoi chiarire $OLDPWDcon un rapido cd ., se ci dovrebbe essere un caso in cui non vuoi che punti ovunque "interessante". Interesserà anche cd -.


16

A livello di programmazione è utile come no-op. Considera un percorso fornito dall'input esterno.

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

Con un percorso come "fred.txt" la directory diventerà ., portando acd .


1
È utile che non generi un errore se sei già nella directory in cui stai navigando, ma non direi che è utile come no-op.
Captain Man

2
@CaptainMan non sta lanciando un errore se sei già nella directory è (in effetti) un no-op. Il dirnamecomando genera .dove necessario per evitare la rottura del codice che prevede di poter dividere un percorso.
roaima,

15

Questo è comune se si dovesse lavorare con un cavo USB difettoso. Dopo che un dispositivo viene disconnesso e ricollegato e montato automaticamente nella stessa directory, è necessario utilizzarlo cd .per farlo funzionare di nuovo.


1
Non dipenderà da quale tipo di dispositivo, da come si accede, dal suo filesystem, dal sistema operativo ecc.?
saluta il

OS, forse. È improbabile che il filesystem sia rilevante, purché il kernel riesca a smontarlo mentre viene utilizzato. In ogni caso, il comando ha il suo utilizzo nella situazione esattamente giusta.
user23013

11

Nota che "." è il modo corretto di specificare il nome del file che è aperto come directory di lavoro corrente di qualsiasi processo (incluso ovviamente un processo di shell) e "." è sempre un nome valido di un file in tutte le directory, inclusa la directory di lavoro corrente. Il nome .potrebbe non essere un nome valido per un file per una determinata istanza di un processo se, per esempio, la directory di lavoro corrente sottostante è stata rimossa (o è andata "male", ad esempio un handle NFS non aggiornato), ma è un nome valido di un file garantito in ogni directory valida.

Quindi . deve essere un argomento valido per qualsiasi comando che accetta il nome di una directory, e quindi nella shell standard cd .deve essere un comando valido.

L' cd .utilità o meno dipende dall'implementazione della shell. Come accennato, può essere utile se la shell reimposta la sua idea interna del percorso completo della directory di lavoro corrente dopo aver chiamato la chdirchiamata di sistema sottostante , ad esempio se la directory sottostante (o qualche suo genitore) è stata rinominata.

Almeno alcune shell che conosco ( /bin/shsu FreeBSD e NetBSD) verranno convertite cd ""in cd ., che può essere probabilmente descritta una funzione per supportare l'uso programmatico in uno script di shell in cui una variabile potrebbe essere usata come parametro (ovvero convertire una sostituzione di variabile vuota in un " "nessuna operazione"), anche se la cronologia del commit di FreeBSD dice che la modifica è stata direttamente dovuta all'aggiunta del supporto POSIX per prevenire un errore chdir(""), da cui i mandati POSIX devono fallire.

Alcune altre shell sostituiranno .con qualsiasi cosa abbiano archiviato come percorso completo nella loro attuale directory di lavoro, e quindi per loro ciò potrebbe consentire il comportamento menzionato nella risposta di Sahil Agarwal .


4

Ho usato questo comando proprio oggi quando ho riformulato il ramo su cui stavo lavorando in Git, da una directory che era stata creata per la prima volta su quello stesso ramo. Il rebase è andato bene, ma in seguito ha git statuslanciato un errore. Dopo cd .tutto era normale.

(Lavoravo in MobaXterm su Windows, per inciso. Nel caso in cui tu stia provando a riprodurlo. Potrebbe non accadere su altri sistemi.)


Ho anche usato questo comando in directory che vengono aggiornate da un processo automatizzato che sposta la vecchia directory e la sostituisce con una nuova (quindi è il più vicino possibile all'atomica). Non è una situazione comune ma cd .è esattamente ciò che è necessario.


Dopo aver letto questa eccellente risposta di Stephane Chazelas:

Ora capisco che i miei casi d'uso sopra funzionano solo perché sto usando bash, in cui cd .è equivalente cd "$PWD". Consiglio vivamente di leggere la risposta collegata.


1

Uso cd .di rieseguire le cose che ho sovraccaricato cdtramite una bashfunzione.

Dal mio ~/.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: questo è già stato suggerito da Sahil in precedenza.

Ciò è utile se ci si trova in una cartella che è stata eliminata e ricreata da un altro processo. Ad esempio, ipotizzando le due sessioni terminali $1e $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

Non sono sicuro se la causa principale di questo comportamento sia esattamente (OS, SHELL, ...?).


Questo è già stato menzionato da altre risposte.
Kusalananda

-8

No, non ha senso. Né negli script, non fa proprio nulla.


2
A seconda della shell, verrebbe ripristinato $PWDe probabilmente chiamerebbe altre funzioni della shell se l'utente ha fornito la propria cdfunzione o alias per sovraccaricare l'integrato cd. Verificherebbe inoltre che la directory corrente è ancora valida e che l'uso corrente ha il permesso di essere lì.
Kusalananda

1) ovviamente non stiamo parlando di possibili alias personalizzati di "cd" ma della build standard 2) come può essere l'uso attuale se non avesse il permesso? Per semplificare, dico solo che nel mondo reale non c'è motivo di usarlo secondo me.
Federico

1
1) no? 2) Il mondo reale non è semplice e Unix è un sistema operativo multiutente. Un utente può modificare le autorizzazioni per le directory e se lo script o la shell interattiva di un altro utente dovesse avere quella directory (o una sua sottodirectory) come directory di lavoro, cd .si lamenterebbe.
Kusalananda

4
Federico, secondo le regole del sito e le mie regole personali, dovrei sottovalutare la tua risposta. Tuttavia, sei nuovo. Benvenuto! Si prega di rivedere alcune delle altre risposte . Dopodiché, se ritieni che la tua risposta sia errata, ti preghiamo di eliminarla. Divertiti a dare altre risposte a questa domanda e altre.
Daveloyall,

2
Soprattutto negli script, a volte "non fa nulla" è esattamente ciò che è necessario.
Matthew Najmon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.