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é$PWDpuò diventare obsoleto in determinate circostanze. - solo in alcune shell (non bash, dash, zsh o ksh93 per istanza)
pwdpotenzialmente fornirà meno informazioni obsolete rispetto a$PWDin 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$PWDdi$(pwd -P), ' non vale la pena utilizzare$(pwd). - in fondo ci cita Stephane usando
cd -P -- "$dir". in caso di dubbi sul valore di$PWDpuoi semprecd -P .prima. questo può anche essere vantaggioso in quanto ottieni anche tutto ciò che$PWDera prima in$OLDPWDe 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/nulldopo 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 $PWDera 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/shdisponibili su Solaris 10 e versioni precedenti ecshshell derivate, dubito che molte altre shell tradizionali non dispongono di questa funzionalità.$()