O bash oferece suporte a bifurcação semelhante ao fork () do C ' s?

Tenho um script que gostaria de bifurcar em um ponto para que duas cópias do mesmo script estejam em execução.

Por exemplo , Gostaria que o seguinte script bash existisse:

echo $$ do_fork() echo $$ 

Se este script bash realmente existisse, a saída esperada seria:

<ProcessA PID> <ProcessB PID> <ProcessA PID> 

ou

<ProcessA PID> <ProcessA PID> <ProcessB PID> 

Há algo que eu possa colocar no lugar de “do_fork ()” para conseguir isso tipo de saída ou para fazer com que o script bash faça um fork do tipo C?

Resposta

Sim. A bifurcação é escrita &:

echo child & echo parent 

O que pode estar confundindo você é que $$ não é o PID do processo shell, é o PID do processo shell original . O objetivo de torná-lo dessa forma é que $$ é um identificador único para uma instância particular do script de shell: ele não muda durante a execução do script e é diferente de $$ em qualquer outra execução simultânea roteiro. Uma maneira de obter o PID real do processo shell é sh -c "echo $PPID".

O fluxo de controle no shell não é o mesmo que C. Se em C você “d write

first(); fork(); second(); third(); 

então um shell equivalente é

after_fork () { second; third; } first; after_fork & after_fork 

A forma simples de shell first; child & parent corresponde ao idioma C usual

first(); if (fork()) parent(); else child(); 

& e $$ existem e se comportam dessa forma em cada shell de estilo Bourne e em (t) csh. $PPID não “existia no Bourne original shell, mas está em POSIX (ou seja, “está em ash, bash, ksh, zsh, …).

Comentários

  • Mas isso ' s basicamente " fork + exec ", não apenas fork.
  • @mattdm: Uh? & é fork, há ' nenhum exec envolvido. Fork + exec é quando você inicia um comando externo.
  • @mattdm: Ah, acho que vejo o que Cory está chegando. Há ' s não exec, mas os dois idiomas têm fluxo de controle diferente.
  • @Gilles: O bash operador de controle & inicia um subshell no qual o comando fornecido é executado. Fork + exec. Você pode ' t apenas colocar & sem nenhum comando anterior para executar.
  • Bem, se " Bifurcação é escrita & " fosse uma afirmação verdadeira, você poderia colocar & em uma linha por si só. Mas você pode ' t. Não ' significa " bifurcação aqui ". Significa " executar o comando anterior em segundo plano em um subshell ".

Resposta

Sim, é chamado de subshells . O código do shell entre parênteses é executado como um subshell (fork). No entanto, o primeiro shell normalmente espera que o filho seja concluído. Você pode torná-lo assíncrono usando o terminador &. Veja-o em ação com algo assim:

#!/bin/bash (sleep 2; echo "subsh 1")& echo "topsh" 

$ bash subsh.sh

Comentários

  • Os parênteses criam um subshell , mas que ' s fork + wait. & é fork sozinho. Se você deseja executar mais de um pipeline no processo filho, é ' o suficiente para usar colchetes (que executam o agrupamento sem criar um processo filho): { sleep 2; echo child; } &

Resposta

Não há nativos bash (ou, que eu saiba, qualquer outro * shell nix típico) maneira de fazer isso. Existem muitas maneiras de gerar processos bifurcados que fazem outra coisa de forma assíncrona, mas não acho que haja nada que siga a semântica exata da chamada de sistema fork ().

A abordagem típica seria será para que seu script de nível superior crie ajudantes que façam exatamente o trabalho que você deseja dividir. Se você fizer $0 $@ & ou qualquer outra coisa, você “começará do início novamente e precisará descobrir isso de alguma forma.

Na verdade, estou começando a pensar em várias maneiras inteligentes de fazer exatamente isso …

Mas , antes que meu cérebro se empolgue muito com isso, acho que uma regra muito boa é: se você está tentando escrever algo em shell e está ficando cheio de truques inteligentes e você deseja mais recursos de linguagem, é hora de mudar para uma linguagem de programação real .

Comentários

  • Embora seu ponto seja bem entendido – bash ' a sintaxe é indiscutivelmente difícil e ' Estando faltando as estruturas de dados e recursos mais elegantes do Perl ou Python, o bash é tão real quanto possível- em seu domínio . É uma linguagem de domínio específico, e eu diria ainda melhor (mais sucinta, mais simples) do que, por exemplo, Python em muitos casos. Você consegue administrar uma sala cheia de sistemas e não conhece o Python? sim. Você pode fazer isso e não saber uma pitada de bash [programação]? Eu não ' não gostaria de tentar. Depois de 30 anos de programação em shell, digo que ' é o mais real possível. E sim, eu falo Python. Mas não ' não confunda os jovens.
  • Dito isso, tecnicamente gosto mais desta resposta. Dizer que " & " é a resposta para o usuário ' s questão, " bifurca em um ponto para que duas cópias do mesmo script estejam sendo executadas " é para meu mente confusa. O que " & " faz, de acordo com o manual do bash, é " … executa o comando [dado] em segundo plano em um subshell. " Ele deve terminar um comando e envolve um fork (tecnicamente , no Linux, um clone ()), mas nesse ponto duas cópias do mesmo script não estão em execução.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *