Bash - executando comandos no shell atual

7

Eu estava lendo o livro de O'Reilly "Unix em poucas palavras", e vi que os comandos podem ser agrupados e executados no shell atual usando o seguinte formato:

{ cmd1 ; cmd2 }

Eu não entendi como isso é possível, pois eu sabia que uma chamada para exec substitui os dados de um shell e, portanto, o shell não pode retornar de uma chamada de sistema exec. Então eu testei o comando e não consigo entender o que aconteceu. Eu entrei em uma linha de comando e não tenho certeza do que a linha de comando pertence.

É apenas a linha de comando do emulador de terminal, separada do shell?

Além disso, como a execução de comandos no shell atual é útil?

    
por user3122885 01.04.2014 / 13:00

3 respostas

5

Para exec ou não para exec

  

uma chamada para exec substitui os dados de um shell e, portanto, o shell não pode retornar de uma chamada de sistema exec.

Mas nem todo comando é o nome de um programa para executar. Então, muitas vezes não há exec chamada envolvida. A principal diferença é que, em contraste com ( cmd1; cmd2; ) , você não obtém outro processo de shell. Ou, talvez, mais corretamente, o shell só irá bifurcar para executar programas filhos, não para executar processos de shell.

Pedido estranho

  

a que pertence a linha de comando.

Como outras respostas apontaram, seu comando estava incompleto. Então a linha de comando pertencia ao bash, que estava esperando pelo fim do seu grupo.

Usa

  

Além disso, como a execução de comandos no shell atual é útil?

… ao contrário do subgrupo

O exemplo mais importante é a configuração de variáveis nesse subcomando. Thy isso:

foo=1; { foo=2; echo $foo; }; ( foo=3; echo $foo; ); echo $foo

Isso imprimirá

2
3
2

Portanto, embora você defina foo=3 dentro de um grupo, esse grupo foi executado em um subshell e suas configurações não se propagaram para o pai.

Outra coisa que vale a pena considerar é o diretório de trabalho atual. { cd foo; make; } deixará você no diretório foo , enquanto ( cd foo; make; ) não alterará o diretório de trabalho atual do seu shell principal.

… ao contrário dos comandos desagrupados

O agrupamento é mais útil se você tiver outro código fora, por exemplo, condicionais

test -f foo && { echo "Foo exists."; rm foo; }

ou redirecionamentos

{ echo "Content of $PWD:"; ls; } | gzip > dirlist.gz
    
por MvG 01.04.2014 / 17:16
9

É porque você não finaliza a segunda linha: { cmd1; cmd2; } está correto. O ponto e vírgula significa "fim de comando".

    
por Jo-Erlend Schinstad 01.04.2014 / 13:02
4

O help builtin pode ser útil mesmo para a palavra-chave { . De help -m { :

NAME
    { ... } - Group commands as a unit.

SYNOPSIS
    { COMMANDS ; }

Portanto, o ponto-e-vírgula ( ; ) é obrigatório após cada comando.

    
por Radu Rădeanu 01.04.2014 / 13:20