É melhor usar $ (pwd) ou $ PWD?

35

Eu encontrei BASEDIR=$(pwd)em um script.

Existem vantagens ou desvantagens sobre o uso BASEDIR="$PWD", além de talvez, que $PWDpossam ser substituídas?

Minix
fonte
3
algumas informações em unix.stackexchange.com/a/79621
Stéphane Chazelas
@ StéphaneChazelas Muito interessante escrever. Estou na metade do caminho e continuarei, mas até onde eu entendi, é melhor usar $(pwd), porque $PWDpode ficar desatualizado em determinadas circunstâncias.
Minix
2
somente em alguns shells (não bash, dash, zsh ou ksh93, por exemplo) pwdfornecerá potencialmente menos informações obsoletas do que $PWDem alguns casos de canto. $(pwd)por outro lado, não funcionará se o diretório atual terminar com caracteres de nova linha, significa bifurcar um processo (exceto no ksh93) e usar recursos extras. Minha opinião é o uso $PWDde $(pwd -P), não vale a pena usar $(pwd).
Stéphane Chazelas
11
no fundo, stephane menciona o uso cd -P -- "$dir". se houver alguma dúvida sobre o valor de $PWDvocê sempre pode cd -P .primeiro. isso também pode ser benéfico, pois você também recebe o que $PWDhavia antes $OLDPWDe pode compará-los depois - e a próxima cd ...; cd -sequência certamente o levará de volta para onde você está agora.
mikeserv

Respostas:

41

Se o bash encontrar, $(pwd)ele executará o comando pwd e será substituído $(pwd)pela saída desse comando. $PWDé uma variável quase sempre definida. O pwd é um comando shell embutido há muito tempo.

Portanto $PWD, falhará se essa variável não estiver definida e $(pwd)falhará se você estiver usando um shell que não suporta a $()construção que, na minha experiência, geralmente é o caso. Então eu usaria $PWD.

Como todo nerd eu tenho meu próprio tutorial de script de shell

Thorsten Staerk
fonte
6
Fiquei com a impressão de que a `command`sintaxe era indesejável e $(command)deve ser preferida. Tanto quanto sei, o último é compatível com POSIX, mas não tenho 100% de certeza.
Minix
6
@Minix De $()fato, é especificado pelo POSIX, portanto, fora do pré POSIX /bin/shdisponível no Solaris 10 e cshshells mais antigos e derivados, duvido que muitos outros shells mainstream não possuam esse recurso.
Jlliagre
@Minix: Aqui está uma pergunta recente neste site que ilustra um problema com o uso de backticks em vez de$()
PM 2Ring
correto, em vez de $ () você pode usar backticks, mas isso não será feito em cascata, então eu não mencionei isso #
Thorsten Staerk
11
Agradável minimap no seu tutorial ....
kbtzr
6

Também deve ser mencionado que $PWDé desejável por causa de seu desempenho. Como variável shell, pode ser resolvida quase instantaneamente. $(pwd)é um pouco mais confuso. Se você inspecionar man 1 bulitinum sistema com o Bash, verá que pwdé um comando interno , o que pode levar você a acreditar que será tão rápido quanto acessar uma variável. No entanto, a $()construção sempre lança um novo subshell (um novo processo) para executar seu conteúdo, independentemente do que está dentro. O mesmo vale para os backticks. De fato, quando eu comparo:

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 subcascas, bem como qualquer outro processo estranho, deve ser evitado sempre que possível. Eles são muito mais caros do que as chamadas de função às quais você pode estar acostumado em outros idiomas.

markasoftware
fonte
Essa é uma visão interessante, mas não sei se estou preocupado com o desempenho nos meus scripts de shell. Também me pergunto como o desempenho mudaria, se o pwd mudar entre consultá-lo.
Minix
@Minix Modifiquei meu script para que o corpo do loop seja echo $PWD; pushd ..; echo $PWD; popd(com adicional >/dev/nullapós cada instrução) e leva 0,05 segundos. Em seguida, removi as instruções de eco (apenas pushd / popd) e demorou 0,03. Portanto, o tempo echo $PWDainda era de 0,01 segundos. Fiz algo semelhante $(pwd)e demorou 2,2 segundos para cada loop, portanto, 1,1 segundos por $(pwd)chamada.
Markasoftware 10/09/19
Para não ser muito exigente, mas posso imaginar, que o cálculo que seria substituído $PWDfosse feito em segundo plano antes da avaliação das declarações de eco. Mas, claramente, o acesso $PWDainda é significativamente mais rápido; portanto, se a compatibilidade não for uma preocupação, esse é definitivamente um motivo para escolher um sobre o outro. Obrigado pelo trabalho em testar isso tão completamente. :)
Minix