Apa perbedaan antara menjalankan skrip Bash vs sumbernya?

Jawaban:

346

Jawaban singkat

Sumber skrip akan menjalankan perintah dalam proses shell saat ini .

Menjalankan skrip akan menjalankan perintah dalam proses shell baru .

Gunakan sumber jika Anda ingin skrip mengubah lingkungan di shell yang sedang berjalan. gunakan jalankan sebaliknya.

Jika Anda masih bingung, silakan baca terus.

Terminologi

Untuk mengklarifikasi beberapa kebingungan umum tentang sintaks untuk dieksekusi dan sintaks ke sumber:

./myscript

Ini akan mengeksekusi myscript asalkan file tersebut dapat dieksekusi dan terletak di direktori saat ini. Titik dan garis miring ( ./) menunjukkan direktori saat ini. Ini diperlukan karena direktori saat ini biasanya tidak (dan biasanya tidak boleh) di $PATH.

myscript

Ini akan mengeksekusi myscript jika file tersebut dapat dieksekusi dan terletak di beberapa direktori di $PATH.

source myscript

Ini akan menjadi sumber myscript . File tidak perlu dieksekusi tetapi harus berupa skrip shell yang valid. File dapat di direktori saat ini atau di direktori di $PATH.

. myscript

Ini juga akan menjadi sumber myscript . "Ejaan" ini adalah yang resmi sebagaimana didefinisikan oleh POSIX . Bash didefinisikan sourcesebagai alias ke titik.

Demonstrasi

Pertimbangkan myscript.shdengan konten berikut:

#!/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

Sebelum kami menjalankan skrip terlebih dahulu kami memeriksa lingkungan saat ini:

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

Variabel FOOtidak didefinisikan dan kita berada di direktori home.

Sekarang kita jalankan file:

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

Periksa kembali lingkungan:

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

Variabel FOOtidak disetel dan direktori kerja tidak berubah.

Keluaran skrip dengan jelas menunjukkan bahwa variabel ditetapkan dan direktori diubah. Pemeriksaan selanjutnya menunjukkan bahwa variabel tidak disetel dan direktori tidak berubah. Apa yang terjadi? Perubahan dibuat di shell baru . The saat shell menelurkan baru shell untuk menjalankan script. Script berjalan di shell baru dan semua perubahan pada lingkungan berlaku di shell baru. Setelah skrip selesai, shell baru dihancurkan. Semua perubahan pada lingkungan di shell baru dihancurkan dengan shell baru. Hanya teks keluaran yang dicetak dalam shell saat ini.

Sekarang kami sumber file:

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

Periksa kembali lingkungan:

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

Variabel FOO diatur dan direktori kerja telah berubah.

Sumber skrip tidak membuat shell baru. Semua perintah dijalankan di shell saat ini dan perubahan ke lingkungan berlaku di shell saat ini.

Perhatikan bahwa dalam contoh sederhana ini output dari eksekusi sama dengan sumber skrip. Ini tidak selalu selalu demikian.

Demonstrasi lain

Pertimbangkan skrip berikut pid.sh:

#!/bin/sh
echo $$

(variabel khusus $$diperluas ke PID dari proses shell yang sedang berjalan)

Pertama cetak PID dari shell saat ini:

$ echo $$
25009

Sumber skrip:

$ source pid.sh
25009

Jalankan skrip, perhatikan PID:

$ ./pid.sh
25011

Sumber lagi:

$ source pid.sh
25009

Jalankan lagi:

$ ./pid.sh
25013

Anda dapat melihat bahwa sumber skrip berjalan dalam proses yang sama saat menjalankan skrip menciptakan proses baru setiap saat. Proses baru itu adalah shell baru yang dibuat untuk eksekusi skrip. Sumber skrip tidak membuat shell baru dan dengan demikian PID tetap sama.

Ringkasan

Baik sumber maupun pengeksekusian skrip akan menjalankan perintah dalam skrip baris demi baris, seolah-olah Anda mengetikkan perintah-perintah itu dengan tangan baris demi baris.

Perbedaannya adalah:

  • Saat Anda menjalankan skrip yang Anda buka shell baru , ketik perintah di shell baru, salin kembali output ke shell Anda saat ini, kemudian tutup shell baru. Setiap perubahan lingkungan hanya akan berlaku di shell baru dan akan hilang setelah shell baru ditutup.
  • Saat Anda sumber skrip Anda mengetik perintah di shell Anda saat ini . Setiap perubahan pada lingkungan akan berlaku dan tetap di shell Anda saat ini.

Gunakan sumber jika Anda ingin skrip mengubah lingkungan di shell yang sedang berjalan. gunakan jalankan sebaliknya.


Lihat juga:

lesmana
sumber
2
Salah satu penggunaan sumber adalah membuat bentuk file konfigurasi yang belum sempurna untuk skrip Anda. Anda mulai dengan mengatur berbagai variabel ke nilai default, dan kemudian sumber di sesuatu seperti myscript.conf - dan skrip bersumber dapat memiliki pernyataan tugas yang menimpa nilai apa pun yang Anda inginkan. Karena skrip bersumber tidak dimulai dengan # / bin / bash, skrip tidak disarankan untuk menjalankannya secara langsung.
LawrenceC
Jadi sumber seperti menjalankannya dalam lingkup global, dan mengeksekusi menciptakan lingkup lokal baru. Bisakah ini diperluas ke fungsi dalam skrip? untuk menjalankan suatu fungsi (biasanya) atau untuk "sumber" itu?
aliteralmind
2
Apakah ada perbedaan antara menggunakan source myscript.shdan . myscript.sh?
Holloway
2
praktis tidak ada perbedaan jika menggunakan bash. source adalah alias untuk dot di bash.
lesmana
1
Saya suka ketika orang memberikan contoh rumit sehingga pemula Linux seperti saya pun bisa mengerti. Terima kasih!
Julius
21

Menjalankan skrip menjalankannya dalam proses anak terpisah, yaitu, contoh shell terpisah dipanggil untuk memproses skrip. Ini berarti bahwa variabel lingkungan apa pun, dll., Yang ditentukan dalam skrip tidak dapat diperbarui dalam shell induk (saat ini).

Sumber skrip berarti diuraikan dan dieksekusi oleh shell saat ini. Seolah-olah Anda mengetik isi skrip. Karena alasan ini, skrip yang dibuat tidak perlu dieksekusi. Tetapi itu harus dapat dieksekusi jika Anda mengeksekusinya tentu saja.

Jika Anda memiliki argumen posisi di shell saat ini, mereka tidak berubah.

Jadi jika saya memiliki file yang a.shberisi:

echo a $*

dan saya lakukan:

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

Saya mendapatkan sesuatu seperti:

a Fri Dec 11 07:34:17 PST 2009

Sedangkan:

$ set `date`
$ ./a.sh

memberi saya:

a

Semoga itu bisa membantu.

Alok
sumber
5
walaupun jawaban ini benar dalam segala hal saya merasa sangat sulit untuk dipahami karena ditunjukkan dengan menggunakan konsep lain (pengaturan parameter posisi), yang, menurut pendapat saya, bahkan lebih membingungkan daripada perbedaan sumber dan mengeksekusi sendiri.
lesmana
9

sumber pada dasarnya sama dengan mengetik setiap baris script pada command prompt satu per satu ...

Eksekusi memulai proses baru dan kemudian menjalankan setiap baris skrip, hanya memodifikasi lingkungan saat ini dengan apa yang dikembalikan.

John Weldon
sumber
6

Selain di atas, mengeksekusi skrip sebagai ./myscriptmembutuhkan izin eksekusi untuk file myscript sementara sumber tidak memerlukan izin eksekusi. Itu sebabnya chmod +x myscripttidak diperlukan sebelumnyasource myscript

abs
sumber
2
Benar, tetapi jika itu masalah, Anda selalu bisa berjalan bash myscript.
Daniel Beck
5

Sumber Anda mendapatkan semua variabel tambahan yang ditentukan dalam skrip.
Jadi, jika Anda memiliki konfigurasi atau definisi fungsi, Anda harus mencari dan tidak mengeksekusi. Eksekusi independen dari lingkungan orang tua.

Arkaitz Jimenez
sumber
3

Jika saya ingat benar, menjalankan skrip menjalankan executable di #!baris dengan file skrip sebagai argumen (biasanya memulai shell baru dan secara efektif sumber skrip ke dalam shell baru, seperti dengan #!/bin/sh);
sedangkan, sumber skrip mengeksekusi setiap baris di lingkungan shell Anda saat ini, yang berguna untuk memutasi shell Anda saat ini (misalnya, menyediakan cara untuk mendefinisikan fungsi shell dan mengekspor variabel lingkungan).

Shekhar
sumber
2

sourceperintah mengeksekusi skrip yang disediakan (izin yang dapat dieksekusi tidak wajib ) di lingkungan shell saat ini , sementara ./mengeksekusi skrip yang dapat dieksekusi yang disediakan di shell baru .

Juga, periksa jawaban ini misalnya: https://superuser.com/a/894748/432100

Harsh Vakharia
sumber