O bash suporta bifurcações semelhantes ao fork de C ()?

17

Eu tenho um script que gostaria de extrair em um ponto para que duas cópias do mesmo script sejam executadas.

Por exemplo, gostaria que o seguinte script bash existisse:

echo $$
do_fork()
echo $$

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

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

ou

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

Existe algo que eu possa colocar no lugar de "do_fork ()" para obter este tipo de saída, ou fazer com que o script bash faça um fork tipo C?

    
por Cory Klein 18.02.2011 / 01:06

3 respostas

16

Sim. Bifurcação é soletrada & :

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 ponto de tornar isso assim é que $$ é um identificador exclusivo para uma instância específica do script de shell: ele não é alterado durante a execução do script e é diferente de $$ em qualquer outro script em execução simultaneamente. Uma maneira de obter o PID real do processo do shell é sh -c 'echo $PPID' .

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

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

então um equivalente de shell é

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

O formulário shell simples first; child & parent corresponde ao idioma usual C

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

& e $$ existem e se comportam dessa maneira em todos os shell estilo Bourne e em (t) csh. $PPID não existia na shell Bourne orignal, mas está em POSIX (por isso está em cinza, bash, ksh, zsh,…).

    
por 18.02.2011 / 01:27
5

Não há nenhuma forma nativa de bash (ou, no meu conhecimento, qualquer outra típica shell * nix) de fazer isso. Há muitas maneiras de gerar processos bifurcados que fazem algo de forma assíncrona, mas não acho que exista nada que siga a semântica exata da chamada do sistema fork ().

A abordagem típica seria fazer com que seu script de nível superior gerasse ajudantes que façam exatamente o trabalho que você deseja dividir. Se você fizer $0 $@ & ou qualquer outra coisa, você começará de novo no começo e precisará descobrir isso de alguma forma.

Na verdade, estou começando a pensar em várias maneiras inteligentes em que se pode fazer isso ...

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

    
por 18.02.2011 / 01:36
5

Sim, chama-se subshells . O código da shell entre parênteses é executado como um subshell (fork). No entanto, o primeiro shell normalmente aguarda a conclusão da criança. Você pode torná-lo assíncrono usando o & terminator. Veja isso em ação com algo assim:

#!/bin/bash

(sleep 2; echo "subsh 1")&
echo "topsh"

$ bash subsh.sh

    
por 18.02.2011 / 06:29

Tags