Strana differenza tra pwd e / bin / pwd


15

Ho aggiunto un link simbolico alla directory corrente con ln -s . aa. Se eseguo cd aa, e successivamente ho eseguito pwd, la risposta è /home/sim/aa.

Ma se lo eseguo /bin/pwdstampa /home/sim(la directory corrente non è cambiata).

Da dove viene questa differenza?

Risposte:


17

Nella maggior parte delle shell tra cui bash, pwdè incorporato un shell:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

Se si utilizza /bin/pwd, è necessario utilizzare l' -Lopzione per ottenere lo stesso risultato di builtin pwd:

$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test

Per impostazione predefinita, /bin/pwdignora i collegamenti simbolici e stampa la directory effettiva.

Da info pwd:

`-L'
`--logical'
     If the contents of the environment variable `PWD' provide an
     absolute name of the current directory with no `.' or `..'
     components, but possibly with symbolic links, then output those
     contents.  Otherwise, fall back to default `-P' handling.

`-P'
`--physical'
     Print a fully resolved name for the current directory.  That is,
     all components of the printed name will be actual directory
     names--none will be symbolic links.

Il built-in pwdinclude il collegamento simbolico per impostazione predefinita, tranne per il fatto che -Pviene utilizzata questa opzione o che il -o physicalset incorporato è attivato.

Da man bash:

pwd [-LP]
              Print the absolute pathname of the  current  working  directory.
              The pathname printed contains no symbolic links if the -P option
              is supplied or the -o physical option to the set builtin command
              is  enabled.  If the -L option is used, the pathname printed may
              contain symbolic links.  The return status is 0 unless an  error
              occurs  while  reading  the  name of the current directory or an
              invalid option is supplied.

Non sono sicuro di capire da dove provengano queste differenze
user3581976,

/bin/pwdignora il collegamento simbolico per impostazione predefinita, leggi la parte info pwdnella mia risposta: stampa un nome completamente risolto per la directory corrente. Cioè, tutti i componenti del nome stampato saranno nomi di directory effettivi - nessuno sarà collegamenti simbolici.
cuonglm,

@ user3581976: vedi il mio aggiornamento per più chiaramente.
cuonglm,

Perché esiste un comando -L per pwd sebbene sia impostato di default? E la shell non usa il comando / bin / pwd per eseguire pwd?
user3581976

2
@ user3581976: L'immagine con cui si avvia la shell set -o physical, ora pwdè l' -Popzione di default, se non si dispone -Ldell'opzione, come si stampa il percorso contiene un collegamento simbolico? Leggi questo https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlper sapere cosa set -o physicalfa.
cuonglm

7

È possibile che un processo interroghi il file system per determinare la sua directory di lavoro corrente, usando un metodo un po 'troppo complicato per essere in argomento come risposta a questa domanda. Questo è ciò che fanno il pwdprogramma e la getcwdfunzione di libreria. All'inizio di Unix, erano gli unici modi per scoprire qual era la tua directory di lavoro. Ecco la parte della risposta alla tua domanda che non riesco a trovare in nessuna delle altre risposte, o in qualsiasi altra parte di questo sito (dopo 42 secondi di ricerca):

  • All'avvio della shell, ottiene la sua directory di lavoro corrente (probabilmente chiamando getcwd).
  • Successivamente, ogni volta che si esegue un cd, pushdo popd, la shell tiene traccia della directory di lavoro usando le funzioni di manipolazione delle stringhe. Per esempio,

    • Se la directory di lavoro è /home/sime si digita cd .., la shell calcola la directory di lavoro /home.
    • Se la directory di lavoro è /home/sime si digita cd ., la shell calcola che la directory di lavoro è ferma /home/sim.
    • Se la directory di lavoro è /home/sime si digita cd aa, la shell calcola la directory di lavoro /home/sim/aa, senza verificare se si aatratta di un collegamento simbolico.

    Lo fa per risparmiare il "costo" della chiamata getcwd. Ma questo è un compromesso, poiché può provocare informazioni errate.

  • Il pwdcomando (incorporato) mostra semplicemente la nozione ricordata / calcolata della shell su quale sia la directory di lavoro.
  • Inoltre, la shell inserisce la sua nozione ricordata / calcolata di ciò che la directory di lavoro è nella variabile di ambiente PWD, per comodità dei processi utente. Un processo non dovrebbe mai fare affidamento su questo se desidera informazioni accurate.

Quindi, la linea di fondo è che la shell può confondersi su dove si trova. Ma se digiti /bin/pwd, questo viene eseguito in un processo separato che non ha accesso alla nozione della shell di ciò che è la directory di lavoro, e quindi determina la vera directory di lavoro stessa, alla vecchia maniera. (Eccezione: il /bin/pwdprogramma può guardare la variabile d'ambiente PWD, e apparentemente lo fa quando si specifica -L.) Ecco un altro esempio di come la shell può essere confusa:

cd /home/sim/aa # Supponiamo che /home, /home/sime /home/sim/aa
# siano tutte directory reali (non collegamenti simbolici).
pwd # Output:, /home/sim/aache è corretto.
mv ../aa ../bb
pwd # Output:, /home/sim/aache non è corretto.
/bin/pwd # Output:, /home/sim/bbche è corretto.


E, nel caso in cui non sei chiaro su questo, se digiti ln -s . aae cd aa, quindi la tua directory di lavoro attuale non è cambiata , non più di quanto faccia quando digiti cd .- perché, questo è essenzialmente quello che stai facendo quando scrivi cd aa.


Grazie, ottima risposta, questo è quello che stavo aspettando;)
user3581976

2
Questa risposta sembra un po ' piegata . C'è molto di più -Lche risparmiare sui costi - ed $PWDè una variabile d'ambiente definita da POSIX specificata dall'utente - le applicazioni dello spazio utente dovrebbero probabilmente fidarsene (qualunque cosa significhi ...?) . Comunque, anche se non sono affatto un fan dei symlink, è una prerogativa dell'utente indirizzare in tutte le direzioni folli che dovrebbe scegliere con loro - e questo è ciò che -Lriguarda più di ogni altra cosa.
Mikeserv,

1
Questa dovrebbe essere la risposta accettata (i collegamenti simbolici non sono il punto della domanda).
Thomas Dickey,
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.