Quais são os possíveis usos do comando exec?

10

Estou aprendendo o execcomando. Eu sei que o execcomando substitui o processo que o iniciou. Portanto, não é possível retornar ao processo que é substituído pelo execcomando.

Pode-se dizer que seu objetivo é tornar impossível retornar ao processo que o iniciou.

Mas quais são os outros usos para ter algo como execdisponível como um comando?

mizech
fonte
1
do artigo da wikipedia: "Os scripts do wrapper costumam usar este comando para executar um programa (diretamente ou por meio de um intérprete ou máquina virtual) após definir variáveis ​​de ambiente ou outra configuração."
knb
1
mais adequado para Ciência da Computação
Anwar
2
Pessoalmente, acho exec ssh server-that-does-byobu-on-login.example.commuito agradável, pois ^ A ^ D desliga o terminal completamente. (De modo mais geral, exec byobu(ou exec screen, exec tmux).
Williham Totland

Respostas:

9

No script do wrapper

exec é usado principalmente em scripts de wrapper.

Se você deseja modificar o ambiente de um programa antes de executar o programa principal, geralmente escreve um script e no final inicia o programa principal. Mas não há necessidade de o script permanecer na memória naquele momento. Portanto, execé usado nesses casos para que o programa principal possa substituir o script mãe.

Aqui está um exemplo prático disso. Seu mate-terminal.wrapperscript vem com o mate-terminal. Ele inicia mate-terminalalguns argumentos extras, verificando os ambientes do usuário.

#!/usr/bin/perl -w

my $login=0;

while ($opt = shift(@ARGV))
{
    if ($opt eq '-display')
    {
        $ENV{'DISPLAY'} = shift(@ARGV);
    }
    elsif ($opt eq '-name')
    {
        $arg = shift(@ARGV);
        push(@args, "--window-with-profile=$arg");
    }
    elsif ($opt eq '-n')
    {
        # Accept but ignore
        print STDERR "$0: to set an icon, please use -name <profile> and set a profile icon\n"
    }
    elsif ($opt eq '-T' || $opt eq '-title')
    {
        push(@args, '-t', shift(@ARGV));
    }
    elsif ($opt eq '-ls')
    {
        $login = 1;
    }
    elsif ($opt eq '+ls')
    {
        $login = 0;
    }
    elsif ($opt eq '-geometry')
    {
        $arg = shift(@ARGV);
        push(@args, "--geometry=$arg");
    }
    elsif ($opt eq '-fn')
    {
        $arg = shift(@ARGV);
        push(@args, "--font=$arg");
    }
    elsif ($opt eq '-fg')
    {
        $arg = shift(@ARGV);
        push(@args, "--foreground=$arg");
    }
    elsif ($opt eq '-bg')
    {
        $arg = shift(@ARGV);
        push(@args, "--background=$arg");
    }
    elsif ($opt eq '-tn')
    {
       $arg = shift(@ARGV);
       push(@args, "--termname=$arg");
    }
    elsif ($opt eq '-e')
    {
        $arg = shift(@ARGV);
        if (@ARGV)
        {
            push(@args, '-x', $arg, @ARGV);
            last;
        }
        else
        {
            push(@args, '-e', $arg);
        }
        last;
    }
    elsif ($opt eq '-h' || $opt eq '--help')
    {
        push(@args, '--help');
    }
}
if ($login == 1)
{
    @args = ('--login', @args);
}
exec('mate-terminal',@args);

O ponto a ser observado aqui é que há uma execchamada que substitui esse script na memória.

Aqui está uma pergunta semelhante respondida no site StackExchange do Unix e Linux - /unix//q/270929/19288

Para redirecionar descritores de arquivo

Outro uso comum execé o redirecionamento de descritores de arquivos. stdin, stdout, stderrPodem ser redirecionados para arquivos usando exec.

  1. Redirecionando stdout- exec 1>filefará com que a saída padrão seja um arquivo nomeado filepara o final da sessão atual do shell. Qualquer coisa a ser exibida no display estará no arquivo.

  2. Redirecionando stdin- Também pode ser usado para redirecionar o stdinarquivo para um arquivo. Por exemplo, se você deseja executar um arquivo de script script.sh, basta redirecioná-lo stdinpara o arquivo usando exec 0<script.sh.

Anwar
fonte
OK. Depois 'mate-terminal' terá o PID que o script do wrapper possui? E usará a memória que o script de wrapper usou? Portanto, o script do wrapper desapareceu. Caso contrário, os dois scripts existiriam como processos separados no sistema (com dois PIDs diferentes)?
Mizech #
@mizech yes. eles usam o mesmo PID
Anwar
@mizech Fico feliz em saber que ajudou :)
Anwar
1
Excelente exemplo, que o torna muito claro
Zanna
Essa resposta é parcial e perde um dos usos importantes (e típicos) execdisso, é o uso no redirecionamento de descritores de arquivo.
heemayl 2/09/16
9

O exec comando substitui o processo atual do shell pelo comando especificado. Normalmente, quando você executa um comando, um novo processo é gerado (bifurcado). O exec comando não gera um novo processo. Em vez disso, o processo atual é sobreposto ao novo comando. Em outras palavras, o execcomando é executado no lugar do shell atual sem criar um novo processo.

Existem três usos mais comuns do comando exec:

1. Substituição do processo

Exemplo-1: Se você abrir um novobashshell como

$ bash 

no pstreeque parece

├─gnome-terminal
        ├─bash───bash───pstree

O bashshell anterior ainda está lá e você tem um novo bashshell. Considerando que, se você abrir um novo shell bash como,

$ exec bash

os pstreeshows

├─gnome-terminal
        ├─bash───pstree

Aqui o antigo bashé substituído por um novo. É particularmente útil sair do login múltiplo em um comando. É mais seguro e erradica a chance de deixar um terminal aberto por engano. Consulte Sair da raiz e do usuário com um comando

Exemplo-2: você pode abrir um arquivo como

$ exec vi filename.txt

Quando você sai, vinão há necessidade de fechar o terminal separadamente, pois o shell já foi substituído. Assim que você fechar o vi, o terminal também será fechado.

2. Um método de redirecionamento de descritores de arquivos nos scripts de shell

O exec comando também pode ser usado em scripts de shell, abrir, fechar e copiar dinamicamente descritores de arquivos. Isso permite executar o redirecionamento de STDIN, STDERR, STDOUT e outros descritores de arquivo para vários arquivos dentro do script de shell, em vez da cadeia de chamada de comando. Se você não especificar um comando ou argumentos, poderá especificar símbolos de redirecionamento e descritores de arquivo para executar essas funções.

Digamos que você tenha um script de shell script.shque deseja ter um arquivo de log script.log, você pode usar execcomo,

LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1

que é equivalente a

./script &>> /path/to/script.log
./script >>  /path/to/script.log 2>&1

3. Criando estágios do processo usando o comando exec

Você também pode usar o comando exec para criar um conjunto de scripts de shell que se executam sequencialmente como estágios do processo. Em vez de gerar novos processos toda vez que você precisar transferir o controle para o próximo script, execute o comando exec.

Nesse caso, a última instrução de cada estágio deve ser um execcomando que chama o próximo estágio.

Veja os usos do execcomando nos scripts de shell para mais.

Nota: Parte do acima é tirada disso.

souravc
fonte
1
Apenas resposta completa (até agora).
heemayl 2/09/16
Todas as vezes que usei exec foram para eficiência. Se você executar um daemon com exec, precisará apenas de um processo ativo em vez de dois. Sair do processo do bash desperdiça alguns MB de RAM, entre outras coisas.
gmatht 3/09/16
2

Tanto quanto sei, também é usado para redirecionar descritores de arquivos (por exemplo, STDOUT, STDERR, STDIN) de um script bash.

Por exemplo, você pode ler um arquivo em vez do teclado usando o redirecionamento STDIN e gravar em um arquivo em vez do terminal usando o redirecionamento STDOUT (ou pode ser STDERR dependendo do programa).

Levin Palm
fonte
1
Esta resposta é parcial e apenas complementa esta resposta .
heemayl 2/09/16