Apa yang dilakukan perintah 'dot space filename' di bash?

30

Saat menggunakan bash shell, saya terkadang menyimpan variabel lingkungan dalam file teks yang saya salin / rekatkan konten, misalnya exports.txt:

export FOO=bar
export FIZZ=buzz

Seseorang menunjukkan kepada saya alih-alih menyalin / menempel, saya bisa mengetik di terminal

. exports.txt

yang akan memiliki efek yang sama dengan salin / tempel.

Apa mekanisme yang digunakan perintah 'dot space filename' ini? Sulit untuk memikirkan istilah pencarian untuk itu.

Saya ingin memahami apa yang sedang terjadi dan rincian yang lebih umum tentang apa yang dilakukan one-liner ini.

iancoleman
sumber
23
Menjalankan help . Ini sangat singkat sehingga mesin Stack Exchange menganggapnya terlalu pendek untuk dijadikan komentar.
Wildcard
5
Saya bertanya-tanya mengapa semua pertanyaan ini muncul juga di situs ini. Mereka telah dijawab berkali-kali di Stack Overflow , Tanya Ubuntu dan Lepaskan & amp; Linux .
fedorqui
Untuk menjalankan dot-space, Anda harus mengetik '. ' args, dengan tanda kutip tunggal atau ganda. Kalau tidak, ruang tanda kutip dimakan oleh bash ketika mem-parsing baris ke token (lihat "pemisahan kata" dalam manual bash).
Peter Cordes
1
Di bash, nama alternatif untuk . aku s source, yang secara harfiah berarti "perintah sumber dari file ini," setidaknya bagi saya.
jpaugh

Jawaban:

40

Itu . Perintah ("dot") adalah sinonim / pintasan untuk built-in shell source perintah.

Itu menyebabkan skrip shell bernama untuk dibaca dan dieksekusi dalam konteks shell saat ini (bukan subkulit). Ini memungkinkan skrip bersumber untuk memodifikasi lingkungan shell panggilan, seperti mengatur variabel dan mendefinisikan fungsi shell atau alias.

Spiff
sumber
49
Sebenarnya, source adalah sinonim / pintas non-standar dan non-portabel untuk POSIX-defined "dot" ( . ) perintah, bukan sebaliknya.
terdon
8
bash menyediakan non-standar source dan yang tidak standar . dalam mode non-POSIX, keduanya mencari direktori saat ini bahkan jika itu bukan bagian dari $PATH. Dalam mode POSIX, ini memberikan standar . yang tidak mencari direktori saat ini, dan tidak source. Dalam mode tidak ada source identik dengan POSIX . perintah.
hvd
26

Sementara dua jawaban yang ada sudah sangat baik, saya merasakan contoh di mana efeknya paling "nyata" sehingga bisa dikatakan, tidak ada.

Katakanlah saya punya file script.sh dengan konten berikut:

cd dir

Jika saya menjalankan skrip ini secara normal ( sh script.sh ), Saya akan melihat ini:

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

Tetapi jika saya di mana sumber script . script.sh ), Saya akan berakhir dengan ini:

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

Perhatikan bagaimana dalam kasus kedua direktori kerja shell utama kami telah berubah!

Ini karena (sebagaimana ditunjukkan dalam jawaban lain) contoh pertama berjalan dalam subkulitnya sendiri (the sh proses kita mulai dengan sh -perintah, ini bisa saja pada dasarnya shell, bash, dash, sebut saja), itu mengubah direktori di sana, tidak melakukan apa pun dan menutup. Sementara contoh kedua berjalan di shell utama kami, dan dengan demikian mengubah direktori di sana!

Olle Kelderman
sumber
4

Berikut ini sebuah contoh.

File skrip: mytest.sh

cat mytest.sh

#!/bin/bash

myvar=1
mystring="Hello World"

jika Anda mencoba mencetak variabel di atas, Anda tidak akan mendapatkan apa-apa

echo $myvar

tetapi jika Anda melakukannya

. mytest.sh

atau

source mytest.sh

lalu

echo $myvar

itu akan mencetak 1

Hanya jawaban visual dari apa yang ditulis Spiff

raism
sumber
Jadi, interpretasikan contoh Anda, gunakan export hanya jika variabel-variabel tersebut akan digunakan dalam subkulit. Saya bisa menghilangkan export dalam file jika variabel hanya digunakan di shell saat ini. Apakah itu benar?
iancoleman
1
Benar sekali dan saya bisa mengatakan ya. Namun penggunaan perintah ekspor lebih bermanfaat atau lebih dapat dimengerti jika Anda berpikir tentang variabel lingkungan shell. Misalnya $ HOME atau $ DISPLAY. Ya, Anda bisa menggunakan perintah ekspor untuk mengekspor variabel pada sesi shell Anda atau subkulit apa pun tetapi itu akan hilang segera setelah Anda mengakhiri sesi itu.
raism