O que o comando 'dot space filename' está fazendo no bash?

30

Ao usar o bash shell, às vezes mantenho variáveis ​​de ambiente em um arquivo de texto no qual copio / colo o conteúdo, por exemplo, export.txt:

export FOO=bar
export FIZZ=buzz

Alguém me mostrou em vez de copiar / colar, eu poderia digitar no terminal

. exports.txt

que teria o mesmo efeito que copiar / colar.

Qual é o mecanismo pelo qual esse comando 'dot space filename' funciona? É difícil pensar em termos de pesquisa para ele.

Eu quero entender o que está acontecendo e os detalhes mais gerais do que esta linha está fazendo.

iancoleman
fonte
23
Executar help . É tão curto que o mecanismo do Stack Exchange acha que é muito curto para ser um comentário.
Curinga
5
Eu me pergunto por que todas essas perguntas ocorrem também neste site. Eles foram respondidos várias vezes no Stack Overflow , Ask Ubuntu e Unix & Linux .
Fedorqui 19/10/16
Para executar o espaço de pontos, você precisa digitar '. ' args, com aspas simples ou duplas. Caso contrário, o espaço não citado é consumido pelo bash quando ele analisa a linha em tokens (consulte "divisão de palavras" no manual do bash).
Peter Cordes
1
No bash, um nome alternativo para .é source, que literalmente significa "comandos de origem deste arquivo", pelo menos para mim.
jpaugh

Respostas:

40

O .comando ("ponto") é um sinônimo / atalho para o comando interno do shell source.

Isso faz com que o script do shell nomeado seja lido e executado no contexto atual do shell (em vez de um subshell). Isso permite que o script de origem modifique o ambiente do shell de chamada, como definir variáveis ​​e definir funções e aliases do shell.

Spiff
fonte
49
Na verdade, sourceé um sinônimo / atalho não padrão e não portátil para o comando "dot" ( ) definido pelo POSIX. , e não o contrário.
terdon
8
O bash fornece um não padrão sourcee um não padrão .no modo não POSIX, os quais pesquisam o diretório atual, mesmo que não faça parte dele $PATH. No modo POSIX, ele fornece um padrão .que não pesquisa o diretório atual, e não source. Em nenhum dos dois modos é sourcesinônimo de .comando do POSIX .
hvd
26

Embora as duas respostas existentes já sejam excelentes, sinto o exemplo em que o efeito é o mais "perceptível", por assim dizer, está faltando.

Digamos que eu tenha um arquivo script.shcom o seguinte conteúdo:

cd dir

Se eu rodasse esse script normalmente ( sh script.sh), veria o seguinte:

olle@OMK2-SERVER:~$ sh script.sh
olle@OMK2-SERVER:~$

Mas se eu onde fonte o script ( . script.sh), acabaria com isso:

olle@OMK2-SERVER:~$ . script.sh
olle@OMK2-SERVER:~/dir$

Observe como, no segundo caso, o diretório de trabalho do nosso shell principal mudou!

Isto porque (como fora apontado em outras respostas) O primeiro exemplo é executado em seu próprio subshell (o shprocesso que começa com a sh-command, este poderia ter sido basicamente qualquer shell, bash, dash, o nome dele), ele muda diretório lá, não faz nada e fecha. Enquanto o segundo exemplo é executado em nosso shell principal e, portanto, altera o diretório lá!

Olle Kelderman
fonte
4

Aqui está um exemplo.

Arquivo de script: mytest.sh

cat mytest.sh

#!/bin/bash

myvar=1
mystring="Hello World"

se você tentar imprimir qualquer uma das variáveis ​​acima, não receberá nada

echo $myvar

mas se você fizer

. mytest.sh

ou

source mytest.sh

e depois

echo $myvar

vai imprimir 1

Apenas uma resposta visual do que Spiff escreveu

raism
fonte
Portanto, para interpretar seu exemplo, use exporté apenas se essas variáveis ​​forem usadas em subshells. Eu poderia omitir exportno arquivo se as variáveis ​​fossem usadas apenas no shell atual. Isso esta certo?
Iancoleman 19/10/16
1
Muito certo e eu poderia dizer que sim. No entanto, o uso do comando export é mais útil ou mais compreensível se você pensar nas variáveis ​​de ambiente do shell. Por exemplo $ HOME ou $ DISPLAY. Sim, você pode usar o comando export para exportar uma variável em sua sessão do shell ou em qualquer subshells, mas desaparecerá assim que você terminar a sessão.
Raism