Co robi polecenie „nazwa pliku kropki” w bash?

30

Podczas korzystania z powłoki bash czasami trzymam zmienne środowiskowe w pliku tekstowym, który kopiuję / wklejam, np. Exports.txt:

export FOO=bar
export FIZZ=buzz

Ktoś pokazał mi zamiast kopiować / wklejać, mogłem wpisać terminal

. exports.txt

co miałoby taki sam efekt jak kopiowanie / wklejanie.

Jaki jest mechanizm działania tego polecenia „nazwa pliku przestrzeni kropkowej”? Trudno wymyślić wyszukiwane hasła.

Chcę zrozumieć, co się dzieje i bardziej ogólne szczegóły tego, co robi ten liniowiec.

iancoleman
źródło
23
Uruchom help . Jest tak krótki, że silnik Stack Exchange uważa, że ​​jest zbyt krótki, aby być komentarzem.
Wildcard
5
Zastanawiam się, dlaczego wszystkie te pytania pojawiają się również na tej stronie. Odpowiedzieli na nie wiele razy w Stack Overflow , Ask Ubuntu oraz Unix & Linux .
fedorqui,
Aby uruchomić kropkę, musisz wpisać '. ' argspojedyncze lub podwójne cudzysłowy. W przeciwnym razie niecytowane miejsce zostanie zjedzone przez bash, kiedy parsuje linię na tokeny (patrz „dzielenie słów” w instrukcji bash).
Peter Cordes,
1
W bash alternatywna nazwa .to source, co dosłownie oznacza „polecenia źródłowe z tego pliku”, przynajmniej dla mnie.
jpaugh

Odpowiedzi:

40

Polecenie .(„kropka”) jest synonimem / skrótem do wbudowanego sourcepolecenia powłoki .

Powoduje, że nazwany skrypt powłoki jest wczytywany i wykonywany w bieżącym kontekście powłoki (a nie w podpowłoce). Umożliwia to skryptowi źródłowemu modyfikowanie środowiska powłoki wywołującej, na przykład ustawianie zmiennych oraz definiowanie funkcji powłoki i aliasów.

Spiff
źródło
49
W rzeczywistości sourcejest niestandardowym i nieprzenośnym synonimem / skrótem do zdefiniowanej przez POSIX. komendy „dot” ( ), a nie na odwrót.
terdon
8
bash zapewnia niestandardowy sourcei niestandardowy .w trybie innym niż POSIX, z których oba przeszukują bieżący katalog, nawet jeśli nie jest on częścią $PATH. W trybie POSIX zapewnia standard, .który nie przeszukuje bieżącego katalogu i nie source. W żadnym trybie nie jest sourcesynonimem .polecenia POSIX .
hvd,
26

Chociaż dwie istniejące odpowiedzi są już doskonałe, wydaje mi się, że brakuje przykładu, w którym efekt jest najbardziej „zauważalny”.

Powiedz, że mam plik script.sho następującej treści:

cd dir

Gdybym uruchomił ten skrypt normalnie ( sh script.sh), zobaczyłbym to:

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

Ale jeśli mam gdzie zdobyć skrypt ( . script.sh), skończyłbym tak:

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

Zauważ, jak w drugim przypadku zmienił się katalog roboczy naszej głównej powłoki!

To dlatego, że (jak wskazano w innych odpowiedzi) pierwszy przykład uruchamia we własnym podpowłoce (w shprocesie Zaczynamy sh-polecenie, to mogło być w zasadzie dowolny powłoki, bash, dash, to nazwę), zmienia się tam katalog, nic nie robi i zamyka. Podczas gdy drugi przykład działa w naszej głównej powłoce, zmienia katalog tam!

Olle Kelderman
źródło
4

Oto przykład.

Plik skryptu: mytest.sh

cat mytest.sh

#!/bin/bash

myvar=1
mystring="Hello World"

jeśli spróbujesz wydrukować dowolną z powyższych zmiennych, nic nie otrzymasz

echo $myvar

ale jeśli tak

. mytest.sh

lub

source mytest.sh

i wtedy

echo $myvar

wydrukuje 1

Tylko wizualna odpowiedź na to, co napisał Spiff

raism
źródło
Tak więc interpretując twój przykład, użycie exportjest tylko wtedy, gdy te zmienne mają być używane w podpowłokach. Mógłbym pominąć exportw pliku, jeśli zmienne mają być używane tylko w bieżącej powłoce. Czy to prawda?
iancoleman,
1
Całkiem słusznie i mógłbym powiedzieć tak. Jednak użycie polecenia eksportu jest bardziej przydatne lub zrozumiałe, jeśli pomyślisz o zmiennych środowiskowych powłoki. Na przykład $ HOME lub $ DISPLAY. Tak, możesz użyć polecenia eksportowania, aby wyeksportować zmienną w sesji powłoki lub dowolnej podpowłoce, ale zniknie ona natychmiast po zakończeniu tej sesji.
raism