2009-12-11 15:24:17 +0000 2009-12-11 15:24:17 +0000
302
302

Qual é a diferença entre a execução de um guião Bash versus a sua aquisição?

Qual é a diferença entre executar um guião Bash como A e obter um guião Bash como B?

A
> ./myscript

B
> source myscript

Respostas (6)

369
369
369
2010-08-16 21:58:48 +0000

Sourcing um script irá executar os comandos no processo current shell.

Executar um script executará os comandos num processo novo shell.

Use a fonte se quiser que o script altere o ambiente na sua shell actualmente em execução. use execute de outra forma.

Se ainda estiver confuso, por favor continue a ler.

Terminologia

Para esclarecer alguma confusão comum sobre a sintaxe a executar e a sintaxe à fonte:

./myscript

Isto irá executar myscript desde que o ficheiro seja executável e localizado no directório actual. O ponto e barra (./) denota o directório actual. Isto é necessário porque o directório actual normalmente não está (e normalmente não deveria estar) em $PATH.

myscript

Isto irá executar myscript se o ficheiro for executável e estiver localizado em algum directório em $PATH.

source myscript

Isto irá fonte myscript. O ficheiro não precisa de ser executável, mas deve ser um script de shell válido. O ficheiro pode estar no directório actual ou num directório em $PATH.

. myscript

Isto também source* myscript. Esta “ortografia” é a oficial tal como definida por POSIX . Bash definido source como um alias para o ponto.

Demonstração

Considerar myscript.sh com o seguinte conteúdo:

#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD

Antes de executarmos o guião, verificamos primeiro o ambiente actual:

$ env | grep FOO
$ echo $PWD
/home/lesmana

A variável FOO não está definida e nós estamos no directório home.

Agora executamos o ficheiro:

$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

Verifique novamente o ambiente:

$ env | grep FOO
$ echo $PWD
/home/lesmana

A variável FOO não está definida e o directório de trabalho não mudou.

A saída do script mostra claramente que a variável foi definida e que o directório foi alterado. A verificação posterior mostra que a variável não está definida e o directório não foi alterado. O que aconteceu? As alterações foram feitas numa nova shell. A current shell gerou uma new shell para executar o script. O script está a correr na nova shell e todas as alterações ao ambiente têm efeito na nova shell. Após a script ter sido feita, a nova shell é destruída. Todas as alterações ao ambiente na nova concha são destruídas com a nova concha. Apenas o texto de saída é impresso na shell actual.

Agora nós código* do ficheiro:

$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

Verifique novamente o ambiente:

$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir

A variável FOO está definida e o directório de trabalho foi alterado.

O script não cria uma nova shell. Todos os comandos são executados na shell actual e as alterações ao ambiente têm efeito na shell actual.

Note que neste exemplo simples o resultado da execução é o mesmo que o sourcing do script. Este nem sempre é necessariamente o caso.

Outra Demonstração

Considere o seguinte script pid.sh:

#!/bin/sh
echo $$

(a variável especial $$ expande-se para o PID do actual processo shell em execução)

Primeira impressão do PID da shell actual:

$ echo $$
25009

Fonte do script:

$ source pid.sh
25009

Executar o script, anote o PID:

$ ./pid.sh
25011

Fonte novamente:

$ source pid.sh
25009

Executar novamente:

$ ./pid.sh
25013

Pode ver que o sourcing do script corre no mesmo processo enquanto executa o script cria sempre um novo processo. Esse novo processo é a nova shell que foi criada para a execução do guião. O sourcing do script não cria uma nova shell e assim o PID permanece o mesmo.

Sumário

Tanto o sourcing como a execução do script executarão os comandos no script linha a linha, como se tivesse digitado esses comandos linha a linha.

As diferenças são:

  • Quando você executar o script que está a abrir uma nova shell, digite os comandos na nova shell, copie a saída de volta para a sua shell actual, depois feche a nova shell. Quaisquer alterações ao ambiente só terão efeito na nova shell e serão perdidas assim que a nova shell for fechada.
  • Quando você cource o script que está a digitar os comandos na sua current shell. Quaisquer alterações ao ambiente entrarão em vigor e permanecerão na sua shell actual.

Use a fonte se quiser que o script altere o ambiente na sua shell actualmente em execução. use execute de outra forma.


Veja também:

23
23
23
2009-12-11 15:35:56 +0000

A execução de um guião executa-o num processo infantil separado, ou seja, é invocada uma instância separada de concha para processar o guião. Isto significa que qualquer variável de ambiente, etc., definida no script não pode ser actualizada na shell pai (actual).

A obtenção de um script significa que este é analisado e executado pela própria shell (actual). É como se tivesse digitado o conteúdo do script. Por esta razão, o script de origem não precisa de ser executável. Mas tem de ser executável se o estiver a executar, claro.

Se tiver argumentos posicionais na shell actual, eles mantêm-se inalterados.

Assim, se eu tiver um ficheiro a.sh contendo:

echo a $*

e eu tenho:

$ set `date`
$ source ./a.sh

recebo algo como:

:

a Fri Dec 11 07:34:17 PST 2009

Considerando

$ set `date`
$ ./a.sh

dá-me:

a

Esperança que ajuda.

9
9
9
2009-12-11 15:27:08 +0000

sourcing é essencialmente o mesmo que digitar cada linha do guião no prompt de comando, um de cada vez…

Execução inicia um novo processo e depois executa cada linha do guião, modificando apenas o ambiente actual pelo que este retorna.

6
6
6
2012-02-23 07:27:43 +0000

Além do acima mencionado, a execução do guião como ./myscript requer permissão de execução para o ficheiro myscript enquanto que o sourcing não requer qualquer permissão de execução. É por isso que o chmod +x myscript não é exigido antes do source myscript.

5
5
5
2009-12-11 15:25:38 +0000

A aquisição obtém todas as variáveis extra definidas no guião.
Assim, se tiver configurações ou definições de funções, deve fazer a fonte e não executar. As execuções são independentes do ambiente dos pais.

2
2
2
2015-03-27 14:04:20 +0000

source executa o script fornecido (a permissão executável é não é obrigatória* ) no current* ambiente shell, enquanto ./ executa o script fornecido executable* numa novo shell.

Também, verifique esta resposta por exemplo: https://superuser.com/a/894748/432100