Eu encontrei BASEDIR=$(pwd)
em um script.
Existem vantagens ou desvantagens sobre usando BASEDIR="$PWD"
, exceto talvez, que $PWD
pudesse ser substituído?
Comentários
Resposta
Se o bash encontrar $(pwd)
, ele executará o comando pwd e substituirá $(pwd)
pela saída deste comando. $PWD
é uma variável que quase sempre é definida. pwd é um comando de shell embutido há muito tempo.
Portanto, $PWD
irá falhar se esta variável não for definida e $(pwd)
irá falhar se você estiver usando um shell que não suporta a construção $()
que deve minha experiência geralmente é o caso. Então, eu usaria $PWD
.
Como todo nerd, tenho meu próprio tutorial de script de shell
Comme nts
- Tive a impressão de que a sintaxe
`command`
era indesejável e$(command)
deve ser o preferido. Pelo que eu sei, este último é compatível com POSIX, mas eu ' não estou 100% certo. - @Minix O
$()
é de fato especificado por POSIX, portanto, fora do POSIX pré/bin/sh
disponível no Solaris 10 e mais antigo ecsh
shells derivados outros shells convencionais não têm esse recurso. - @Minix: Aqui está uma pergunta recente neste site que ilustra um problema com o uso de crases em vez de
$()
- correto, em vez de $ () você poderia usar crases, mas isso não será em cascata, então não mencionei isso
- Belo minimapa em seu tutorial …
Resposta
Também deve ser mencionado que $PWD
é desejável por causa de seu desempenho. Como uma variável de shell, pode ser resolvida quase instantaneamente. $(pwd)
é um pouco mais confuso. Se você inspecionar man 1 bulitin
em um sistema com Bash, verá que pwd
é um comando embutido, que pode levar você a acredito que será tão rápido quanto acessar uma variável. No entanto, a construção $()
sempre inicia um novo subshell (um novo processo) para executar seu conteúdo, independentemente do que está dentro . A mesma coisa vale para backticks. De fato, quando faço o benchmark:
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)
Recebo 1,52 segundos para a $(pwd)
chamada e 0,018 segundos para $PWD
. O lançamento desnecessário de subshells, bem como de quaisquer outros processos estranhos, deve ser evitado sempre que possível. Eles são muito mais caros do que chamadas de função com as quais você está acostumado em outros idiomas.
Comentários
- Que ' é uma abordagem interessante sobre isso, mas eu não ' não sei se estou preocupado com o desempenho em meus scripts de shell. Também me pergunto como o desempenho mudaria, se o pwd muda entre as consultas.
- @Minix Modifiquei meu script para que o corpo do loop seja
echo $PWD; pushd ..; echo $PWD; popd
(com>/dev/null
após cada instrução), e leva 0,05 segundos. Em seguida, removi as instruções echo (apenas pushd / popd) e levou 0,03.Portanto, o tempo porecho $PWD
ainda era de 0,01 segundos ou mais. Fiz algo semelhante com$(pwd)
e levou 2,2 segundos para cada loop, então 1,1 segundos por$(pwd)
chamada. - Não quero ser muito exigente, mas posso imaginar que o cálculo que substituiria
$PWD
seria feito em segundo plano antes da avaliação das instruções de eco. Mas, claramente, acessar$PWD
ainda é significativamente mais rápido, portanto, se a compatibilidade não for uma preocupação, esse é definitivamente um motivo para escolher um em vez do outro. Obrigado pelo trabalho em testar isso tão completamente. 🙂
$(pwd)
, porque$PWD
pode ficar desatualizado em certas circunstâncias.pwd
potencialmente fornecer menos informações obsoletas do que$PWD
em alguns casos extremos.$(pwd)
por outro lado não ' não funciona se o diretório atual termina em caracteres de nova linha, significa bifurcação de um processo (exceto em ksh93) e usar recursos extras. Minha visão é usar$PWD
de$(pwd -P)
, ' não vale a pena usar$(pwd)
.cd -P -- "$dir"
. se houver alguma dúvida sobre o valor de$PWD
, você sempre podecd -P .
primeiro. isso também pode ser benéfico, pois você também obtém o que$PWD
estava antes disso em$OLDPWD
e pode compará-los depois – e no próximocd ...; cd -
sequência certamente o trará de volta para onde você está agora.