Por que a expansão do shell no popd não remove um diretório da pilha?

3

Quando uso popd sozinho, ele remove um diretório da pilha e me leva para esse diretório. No entanto, se eu fizer cd $(popd) , nenhum diretório será removido da pilha.

Como o processo é simplesmente bifurcado e o resultado é colocado no lugar da expansão do shell, por que um diretório não é retirado da pilha?

    
por Adam Thompson 09.08.2016 / 01:42

3 respostas

6

A substituição do comando $(…) executa o comando em um subshell. Uma subcamada começa como uma cópia idêntica da concha principal, mas a partir desse ponto a concha principal e a subcamada vivem sua própria vida.

  1. O processo do shell cria um tubo e garfos.
  2. O filho executa popd com sua saída conectada ao canal e, em seguida, sai.
  3. O pai lê os dados do pipe e os substitui na linha de comando.

Como popd é executado no processo filho, seu efeito é limitado ao processo filho. O diretório é retirado da pilha da pilha da criança. Nada acontece com a pilha no pai.

¹ Quase idêntico; as diferenças não são relevantes aqui.

    
por 09.08.2016 / 01:53
8

A sintaxe $(...) não é "expansão de shell", é "substituição de comando".

Com esta sintaxe, um sub-shell é criado, o comando dentro é executado e o stdout retorna na linha comamnd. Então, por exemplo,

x=$(cd /tmp ; ls)

executará o comando cd no subshell, o que significa que o diretório atual do processo principal não foi alterado.

De maneira semelhante, cd $(popd) fará com que popd seja executado no processo filho e, portanto, impactará apenas o processo filho; o processo pai está intacto.

Você pode ver que isso afetou o processo filho com este teste simples:

$ pushd /tmp
/tmp ~
$ pushd /
/ /tmp ~
$ dirs
/ /tmp ~
$ cd $(popd ; dirs >&2)
/tmp ~
$ dirs
/tmp /tmp ~

O dirs >&2 mostra que dentro da shell $(...) a pilha de diretórios foi estourada, mas porque este é um processo filho , a pilha pai é intocada.

    
por 09.08.2016 / 01:51
3

pushd e popd mantêm a pilha em uma variável chamada DIRSTACK , que muda no subshell, mas permanece inalterada no shell pai, assim como qualquer outra variável de ambiente.

Leia mais .

    
por 09.08.2016 / 01:53