Pesquisa de site

Aprenda a diferença entre sourcing e bifurcação no Bash


O foco principal deste artigo é entender claramente o que acontece quando você executa o script versus fonte do script no bash. Primeiro, entenderemos claramente como o programa é enviado quando você chama o script de diferentes maneiras.

NOTA: criar o script com uma extensão não importa. O script funcionará bem mesmo sem extensões.

Basicamente, todo script começa com uma linha chamada shebang(#!). O símbolo Hash no bash será interpretado como comentários, mas shebang tem um significado especial. Diz ao bash para enviar o programa em qualquer intérprete que você mencionou em shebang.

Abaixo está um programa de exemplo e estou especificando o bash como meu intérprete.

cat >> Hello_World.sh
#!/usr/bin/env bash
echo "Hello world"

chmod +x Hello_world.sh

Agora, para executar o script, você pode fazer isso de duas maneiras.

  • Use um caminho relativo para chamar o script. Vá para o diretório onde o script está presente e execute ./Hello_world.sh.
  • Use o caminho absoluto para chamar o script. De qualquer lugar no sistema de arquivos, digite o caminho completo para o script.
./Hello_world.sh
pwd
/home/karthick/Hello_world

Agora vamos ver o que acontece quando você tenta enviar seu programa sem shebang. Na ausência de shebang, o programa será submetido a qualquer shell atual que você esteja executando. No meu caso, é Bash (/bin/bash).

Deixe-me demonstrar um exemplo. Estou criando um script python sem shebang e quando chamo o programa, bash não sabe que deve enviar este programa ao interpretador python, em vez disso, ele executará o programa no shell atual.

cat > run-py.py
echo $SHELL
print("Hello world")

chmod +x run-py.py
./run-py.py

Neste caso, você pode chamar o programa mencionando a qual interpretador ele deve ser submetido ou apenas adicionar a linha shebang que é sempre recomendada.

which python3
$(which python3) /home/karthick/run_py.py

Agora que você sabe como chamar o script, o próximo passo seria entender o que acontece quando chamamos o script. Quando você invoca o script conforme mostrado nos exemplos acima, ele criará um processo filho (forking) e o script será enviado ao processo filho. Executei um script de exemplo que apenas executará o seguinte comando e mostrará que o script foi enviado a um processo filho.

ps -ef --forest | grep -i bash

Pode haver vários processos filhos como parte do script e isso depende do nosso código. Deve-se notar que as variáveis ambientais criadas pelo subscrito serão eliminadas assim que for concluído. Um processo filho pode acessar variáveis criadas pelo processo pai exportando-as. Mas o processo pai não pode acessar as variáveis criadas pelo processo filho.

Dê uma olhada nos artigos abaixo para entender mais sobre como as variáveis funcionam e como exportá-las.

  • Compreendendo e escrevendo ‘variáveis Linux’ em scripts Shell
  • Aprenda a diferença entre $$e $BASHPID no Bash

Obtendo o roteiro

Source” é um comando interno do shell que lê o arquivo passado como argumento para ele e executa o código no ambiente shell atual. Um caso de uso apropriado que você usa principalmente é modificar sua configuração em .bashrc ou .bash_profile e recarregar as alterações usando o comando source.

type -a source

Existem duas formas sintáticas de executar o comando source. Você pode escolher qualquer uma entre duas sintaxes e isso é de escolha pessoal.

source FILE_NAME [ARGUMENTS]
. FILE_NAME [ARGUMENTS]

Deixe-me demonstrar como a fonte realmente funciona. Vou criar dois scripts de shell. O primeiro script (Module.sh) conterá algumas variáveis e funções. O segundo script (Main.sh) imprimirá a variável e chamará a função.

Arquivo Module.sh.

#!/usr/bin/env bash

VAR1=$(echo "Welcome to $1")

function f1(){
  echo “Function f1 is called”
}

Arquivo Main.sh.

#!/usr/bin/env bash

echo $VAR1
f1

Defina a permissão de execução do script e chame o script principal “main.sh ”. Agora, este script tentará encontrar a função f1 e a variável VAR1 no ambiente shell atual e falhará com o comando não encontrado.

bash main.sh

Agora vamos executar o comando source dentro do script que carregará a variável e as funções no ambiente shell atual e que estará acessível por “main.sh ”.

Arquivo Module.sh.

#!/usr/bin/env bash

VAR1=$(echo "Welcome to $1")

function f1(){
  echo "Function f1 is called"
}

Arquivo Main.sh.

#!/usr/bin/env bash

source module.sh Tecmint
echo $VAR1
f1

Agora execute o script novamente e veja.

bash main.sh

O source é muito útil no bash para seguir a abordagem de programação modular na criação de nossos scripts de shell. Podemos dividir nosso código em módulos menores e podem ser usados em muitos programas. Desta forma, podemos seguir o princípio DRY (Não se repita).

É isso neste artigo. Discutimos brevemente a diferença entre sourcing e fork no bash. Leia o artigo e compartilhe seus valiosos comentários conosco.