Ho incontrato BASEDIR=$(pwd)
in uno script.
Ci sono vantaggi o svantaggi rispetto utilizzando BASEDIR="$PWD"
, a parte forse, che $PWD
potrebbe essere sovrascritto?
Commenti
- alcune informazioni su unix.stackexchange.com/a/79621
- @St é phaneChazelas Scrittura molto interessante. Sono ' solo a metà e continuerò, ma per quanto ho capito, ' è meglio usare
$(pwd)
, perché$PWD
può diventare obsoleto in determinate circostanze. - solo in alcune shell (non bash, dash, zsh o ksh93 per istanza)
pwd
potenzialmente fornirà meno informazioni obsolete rispetto a$PWD
in alcuni casi estremi.$(pwd)
daltro canto ' non funziona se la directory corrente termina con caratteri di nuova riga, significa eseguire il fork di un processo (eccetto in ksh93) e usa risorse extra. La mia opinione è utilizzare$PWD
di$(pwd -P)
, ' non vale la pena utilizzare$(pwd)
. - in fondo ci cita Stephane usando
cd -P -- "$dir"
. in caso di dubbi sul valore di$PWD
puoi semprecd -P .
prima. questo può anche essere vantaggioso in quanto ottieni anche tutto ciò che$PWD
era prima in$OLDPWD
e quindi puoi confrontarli in seguito – e il successivocd ...; cd -
la sequenza ti riporterà sicuramente dove sei ora.
Rispondi
Se bash incontra $(pwd)
eseguirà il comando pwd e sostituirà $(pwd)
con loutput di questo comando. $PWD
è una variabile che è quasi sempre impostata. pwd è un comando di shell incorporato da molto tempo.
Quindi $PWD
fallirà se questa variabile non è impostata e $(pwd)
fallirà se utilizzi una shell che non supporta il costrutto $()
che deve la mia esperienza è abbastanza frequente. Quindi userei $PWD
.
Come ogni nerd ho il mio tutorial sullo scripting di shell
Comme nts
Risposta
Va anche detto che $PWD
è desiderabile per le sue prestazioni. Come variabile di shell, può essere risolta quasi istantaneamente. $(pwd)
crea un po più di confusione. Se controlli man 1 bulitin
su un sistema con Bash, vedrai che pwd
è un comando integrato, che potrebbe portarti a credo che sarà veloce quanto accedere a una variabile. Tuttavia, il costrutto $()
lancia sempre una nuova subshell (un nuovo processo) per eseguire i suoi contenuti, indipendentemente da cosa cè dentro . La stessa cosa vale per i backtick. Infatti, quando lo confronto:
echo "Benchmarking $(pwd)..." time (for i in {1..1000}; do echo $(pwd) > /dev/null; done) echo "Benchmarking $PWD..." time (for i in {1..1000}; do echo $PWD > /dev/null; done)
ottengo 1,52 secondi per la chiamata $(pwd)
e 0,018 secondi per $PWD
. Il lancio non necessario di subshell, così come qualsiasi altro processo estraneo, dovrebbe essere evitato quando possibile. Sono molto più costose delle chiamate di funzione a cui potresti essere abituato in altre lingue.
Commenti
- Questo ' è uninterpretazione interessante, ma ' non so se sono preoccupato per le prestazioni dei miei script di shell. Mi chiedo anche come cambierebbero le prestazioni, se il pwd cambia tra una query e laltra.
- @Minix Ho modificato il mio script in modo che il corpo del ciclo sia
echo $PWD; pushd ..; echo $PWD; popd
(con>/dev/null
dopo ogni istruzione) e ci vogliono 0,05 secondi, quindi ho rimosso le istruzioni echo (solo pushd / popd) e ci sono voluti 0,03.Quindi il tempo perecho $PWD
era ancora 0,01 secondi circa. Ho fatto qualcosa di simile con$(pwd)
e ci sono voluti 2,2 secondi per ogni ciclo, quindi 1,1 secondi per$(pwd)
chiamata. - Non per essere troppo esigente, ma posso immaginare che il calcolo, che sostituirebbe
$PWD
, sarebbe stato eseguito in background prima della valutazione delle istruzioni echo. Ma chiaramente, laccesso a$PWD
è ancora significativamente più veloce, quindi se la compatibilità non è un problema, questo è sicuramente un motivo per scegliere uno piuttosto che laltro. Grazie per il lavoro svolto nel testarlo così a fondo. 🙂
`command`
fosse indesiderabile e$(command)
è da preferire. Per quanto ne so, questultimo è conforme a POSIX, ma ' non ne sono sicuro al 100%.$()
è effettivamente specificato da POSIX quindi al di fuori delle/bin/sh
disponibili su Solaris 10 e versioni precedenti ecsh
shell derivate, dubito che molte altre shell tradizionali non dispongono di questa funzionalità.$()