Jag stötte på BASEDIR=$(pwd)
i ett skript.
Finns det några fördelar eller nackdelar över använder BASEDIR="$PWD"
, annat än kanske, att $PWD
skulle kunna skrivas över?
Kommentarer
- lite info på unix.stackexchange.com/a/79621
- @St é phaneChazelas Mycket intressant skriv upp. Jag ' är bara halvvägs och kommer att fortsätta, men så vitt jag förstod det är det ' bättre att använda
$(pwd)
, eftersom$PWD
kan bli föråldrad under vissa omständigheter. - endast i vissa skal (inte bash, dash, zsh eller ksh93 för instans) kommer
pwd
potentiellt att ge dig mindre inaktuell information än$PWD
i vissa hörnfall.$(pwd)
å andra sidan fungerar inte ' om den aktuella katalogen slutar med nya radtecken, betyder att förfalska en process (utom i ksh93) och använda extra resurser. Min åsikt är att använda$PWD
av$(pwd -P)
, det ' är inte värt att använda$(pwd)
. - längst ner där nämner stephane med
cd -P -- "$dir"
. om det finns något tvivel om värdet av$PWD
kan du alltidcd -P .
först. Detta kan också vara fördelaktigt genom att du också får vad$PWD
som var innan det i$OLDPWD
och så kan jämföra dem efteråt – och nästacd ...; cd -
sekvensen kommer säkert att föra dig tillbaka dit du är nu.
Svar
Om bash möter $(pwd)
kommer kommandot pwd att köras och ersätter $(pwd)
med detta kommandos utdata. $PWD
är en variabel som nästan alltid är inställd. pwd är ett inbyggt skalkommando sedan länge.
Så $PWD
kommer att misslyckas om denna variabel inte är inställd och $(pwd)
misslyckas om du använder ett skal som inte stöder $()
-konstruktionen som ska min erfarenhet är ganska ofta. Så jag skulle använda $PWD
.
Som varje nörd har jag min egen handledning om skalskriptning
Komma nts
Svar
Det bör också nämnas att $PWD
är önskvärt på grund av dess prestanda. Som en skalvariabel kan den lösas nästan direkt. $(pwd)
är lite mer förvirrande. Om du inspekterar man 1 bulitin
på ett system med Bash, ser du att pwd
är ett inbyggt kommando som kan leda dig till tror att det kommer att vara lika snabbt som att få tillgång till en variabel. $()
-konstruktionen startar alltid en ny subshell (en ny process) för att köra dess innehåll, oavsett vad som finns inuti . Samma sak gäller backticks. När jag riktigt riktmärker det:
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)
får jag 1,52 sekunder för $(pwd)
samtalet och 0,018 sekunder för $PWD
. Onödig lansering av subshells, liksom andra främmande processer, bör undvikas när det är möjligt. De ”är mycket dyrare än funktionssamtal som du kan vara van vid på andra språk.
Kommentarer
- Att ' är en intressant uppfattning om det, men jag vet inte ' om jag är orolig för prestanda på mina skalmanus. Jag undrar också hur föreställningen skulle förändras, om pwd ändras mellan att fråga det.
- @Minix Jag ändrade mitt skript så att loop-kroppen skulle vara
echo $PWD; pushd ..; echo $PWD; popd
(med ytterligare>/dev/null
efter varje uttalande), och det tar 0,05 sekunder. Jag tog sedan bort ekosatserna (endast pushd / popd) och det tog 0,03.Så tiden perecho $PWD
var fortfarande 0,01 sekunder eller så. Jag gjorde något liknande med$(pwd)
, och det tog 2,2 sekunder för varje slinga, så 1,1 sekunder per$(pwd)
samtal. - Att inte vara för kräsen, men jag kan föreställa mig att beräkningen, som skulle ersätta
$PWD
, skulle göras i bakgrunden innan utvärderingen av ekouttalandena. Men det är tydligt att åtkomst till$PWD
fortfarande är betydligt snabbare, så om kompatibilitet inte är ett problem är det definitivt en anledning att välja varandra. Tack för arbetet med att testa detta så noggrant. 🙂
`command`
syntax var oönskad och$(command)
är att föredra. Såvitt jag vet är det senare POSIX-kompatibelt, men jag ' är inte 100% säker.$()
specificeras verkligen av POSIX så utanför pre POSIX/bin/sh
tillgänglig på Solaris 10 och äldre ochcsh
härledda skal, jag tvivlar på många andra vanliga skal saknar den funktionen.$()