<Anterior | Conteúdo | Próxima>
Substituição de Processo
Embora pareçam semelhantes e possam ser usados para combinar streams para redirecionamento, há uma diferença importante entre comandos de grupo e subshells. Enquanto um comando de grupo executa todos os seus comandos no shell atual, um subshell (como o nome sugere) executa seus comandos em uma cópia filho do shell atual. Isso significa que o ambiente é copiado e fornecido a uma nova instância do shell. Quando o subshell sai, a cópia do ambiente é perdida, portanto, todas as alterações feitas no ambiente do subshell (incluindo atribuição de variável) também são perdidas. Portanto, na maioria dos casos, a menos que um script exija um subshell, os comandos de grupo são preferíveis aos subshells. Os comandos de grupo são mais rápidos e requerem menos memória.
Vimos um exemplo do problema de ambiente de subcamada no Capítulo 28, quando descobrimos que um ler O comando em um pipeline não funciona como esperamos intuitivamente. Para recapitular, se construirmos um pipeline como este:
echo "foo" | leia o eco $ REPLY
echo "foo" | leia o eco $ REPLY
O conteúdo do RESPOSTA variável está sempre vazia porque o ler comando é executado em um subshell, e sua cópia do RESPOSTA é destruído quando o subshell termina.
Como os comandos em pipelines são sempre executados em subshells, qualquer comando que atribua variáveis encontrará esse problema. Felizmente, o shell fornece uma forma exótica de expansão chamada substituição de processo que pode ser usado para solucionar esse problema.
A substituição de processo é expressa de duas maneiras: Para processos que produzem saída padrão:
<(Lista)
ou, para processos que recebem entrada padrão:
>(Lista)
onde Lista é uma lista de comandos.
Para resolver nosso problema com ler, podemos empregar substituição de processo como esta:
leia <<(echo "foo") echo $ REPLY
leia <<(echo "foo") echo $ REPLY
A substituição de processo nos permite tratar a saída de um subshell como um arquivo comum para fins de redirecionamento. Na verdade, por se tratar de uma forma de expansão, podemos examinar seu valor real:
[me @ linuxbox ~] $ echo <(echo "foo")
/ dev / fd / 63
[me @ linuxbox ~] $ echo <(echo "foo")
/ dev / fd / 63
Usando eco para ver o resultado da expansão, vemos que a saída do subshell está sendo fornecida por um arquivo chamado / dev / fd / 63.
A substituição do processo é frequentemente usada com loops contendo ler. Aqui está um exemplo de um
loop de leitura que processa o conteúdo de uma listagem de diretório criada por um subshell:
#! / Bin / bash
# pro-sub: demonstração de substituição de processo
enquanto read attr links proprietário tamanho do grupo data hora nome do arquivo; fazer gato << - EOF
Nome do arquivo: $ filename Tamanho: $ size
Proprietário: $ owner
Grupo: $ group Modificado: $ date $ time Links: $ links Atributos: $ attr
EOF
feito <<(ls -l | cauda -n +2)
#! / Bin / bash
# pro-sub: demonstração de substituição de processo
enquanto read attr links proprietário tamanho do grupo data hora nome do arquivo; fazer gato << - EOF
Nome do arquivo: $ filename Tamanho: $ size
Proprietário: $ owner
Grupo: $ group Modificado: $ date $ time Links: $ links Atributos: $ attr
EOF
feito <<(ls -l | cauda -n +2)
O loop executa ler para cada linha de uma listagem de diretório. A listagem em si é produzida na linha final do roteiro. Esta linha redireciona a saída da substituição do processo para a entrada padrão do loop. o cauda O comando está incluído no pipeline de substituição do processo para eliminar a primeira linha da listagem, que não é necessária.
Quando executado, o script produz uma saída como esta:
[me @ linuxbox ~] $ pró-sub | cabeça -n 20
Nome do arquivo: endereços.ldif Tamanho: 14540
Dono: eu
Grupo: eu
Modified: 2009-04-02 11:12
[me @ linuxbox ~] $ pró-sub | cabeça -n 20
Nome do arquivo: endereços.ldif Tamanho: 14540
Dono: eu
Grupo: eu
Modified: 2009-04-02 11:12
Links:
1
Links:
Atributos: -rw-r - r--
Nome do arquivo: bin
Tamanho: 4096
Dono: eu
Grupo: eu
Modified: 2009-07-10 07:31
Ligações: 2
Atributos: drwxr-xr-x
Nome do arquivo: bookmarks.html Tamanho: 394213
Dono: eu
Grupo: eu
Atributos: -rw-r - r--
Nome do arquivo: bin
Tamanho: 4096
Dono: eu
Grupo: eu
Modified: 2009-07-10 07:31
Ligações: 2
Atributos: drwxr-xr-x
Nome do arquivo: bookmarks.html Tamanho: 394213
Dono: eu
Grupo: eu