Sumber skrip akan menjalankan perintah di saat ini proses shell.
Melaksanakan skrip akan menjalankan perintah dalam baru proses shell.
Gunakan sumber jika Anda ingin skrip mengubah lingkungan di shell yang sedang berjalan. gunakan jalankan sebaliknya.
"lingkungan" adalah hal-hal seperti direktori kerja saat ini dan variabel lingkungan. juga pengaturan shell (antara lain sejarah dan fitur penyelesaian). masih ada lagi tapi itu yang paling terlihat.
Jika Anda ingin detail lebih lanjut, baca terus.
Terminologi
Untuk mengklarifikasi beberapa kebingungan umum tentang sintaks yang akan dieksekusi dan sintaks ke sumber:
./myscript
Ini akan dijalankan myscript
asalkan file tersebut dapat dieksekusi dan terletak di direktori saat ini. Titik dan garis miring terdepan (./
) menunjukkan direktori saat ini. Ini diperlukan karena direktori saat ini biasanya tidak (dan biasanya tidak boleh) di $PATH
.
myscript
Ini akan dijalankan myscript
jika file dapat dieksekusi dan terletak di beberapa direktori di $PATH
.
source myscript
Ini akan sumber myscript
. File tersebut tidak perlu dapat dieksekusi tetapi harus berupa skrip shell yang valid. File dapat berada di direktori saat ini atau di direktori di $PATH
.
. myscript
Ini juga akan sumber myscript
. "Ejaan" ini adalah yang resmi seperti yang didefinisikan oleh POSIX. Bash mendefinisikan source
sebagai alias untuk titik.
dan untuk kelengkapan:
exec myscript
Ini akan menghentikan shell saat ini dan kemudian mengeksekusi myscript sebagai pengganti shell yang dihentikan. Itu berarti ketika skrip saya selesai, tidak ada shell lama untuk dikembalikan. exec
kuat tetapi jarang dibutuhkan.
Saya menaruh beberapa tautan di bagian akhir untuk informasi lebih lanjut tentang topik ini.
Demonstrasi
Pertimbangkan myscript.sh
dengan 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 kita mengeksekusi skrip terlebih dahulu kita periksa lingkungan saat ini:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Variabel FOO
tidak ditentukan dan kami berada di direktori home.
Sekarang kita mengeksekusi file:
$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Periksa lingkungan lagi:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Variabel FOO
tidak disetel dan direktori kerja tidak berubah.
Keluaran skrip dengan jelas menunjukkan bahwa variabel telah disetel dan direktori telah diubah. Pemeriksaan sesudahnya menunjukkan bahwa variabel tidak disetel dan direktori tidak diubah. Apa yang terjadi? Perubahan dibuat dalam baru kerang. saat ini shell menelurkan baru shell untuk menjalankan skrip. Skrip berjalan di shell baru dan semua perubahan pada lingkungan berlaku di shell baru. Setelah skrip selesai, shell baru dihancurkan. Semua perubahan lingkungan di shell baru dihancurkan dengan shell baru. Hanya teks keluaran yang dicetak di shell saat ini.
Sekarang kami sumber file:
$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Periksa lingkungan lagi:
$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir
Variabel FOO disetel dan direktori kerja telah berubah.
Sumber skrip tidak membuat shell baru. Semua perintah dijalankan di shell saat ini dan perubahan pada lingkungan berlaku di shell saat ini.
Perhatikan bahwa dalam contoh sederhana ini, keluaran dari eksekusi sama dengan sumber skrip. Ini belum tentu selalu demikian.
Demonstrasi Lain
Pertimbangkan untuk mengikuti skrip pid.sh
:
#!/bin/sh
echo $$
(variabel khusus $$
memperluas 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, catat 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 membuat proses baru setiap saat. Proses baru itu adalah baru shell yang dibuat untuk eksekusi skrip. Sumber skrip tidak membuat shell baru dan dengan demikian PID tetap sama.
Ringkasan
Sumber dan eksekusi skrip akan menjalankan perintah di skrip baris demi baris, seolah-olah Anda mengetik perintah tersebut secara manual baris demi baris.
Perbedaannya adalah:
- Saat Anda mengeksekusi skrip yang Anda buka baru shell, ketik perintah di shell baru, salin hasilnya kembali ke shell Anda saat ini, lalu tutup shell baru. Setiap perubahan pada lingkungan hanya akan berlaku di shell baru dan akan hilang setelah shell baru ditutup.
- Saat Anda sumber skrip Anda mengetik perintah di saat ini Anda kerang. Setiap perubahan pada lingkungan akan diterapkan dan tetap berada di shell Anda saat ini.
Gunakan sumber jika Anda ingin skrip mengubah lingkungan di shell yang sedang berjalan. gunakan jalankan sebaliknya.
Lihat juga:
- https://stackoverflow.com/questions/6331075/why-do-you-need-dot-slash-before-script-name-to-run-it-in-bash
- https://askubuntu.com/questions/182012/is-there-a-difference-between-and-source-in-bash-after-all
- https://stackoverflow.com/questions/18351198/what-are-the-uses-of-the-exec-command-in-shell-scripts
Mengeksekusi skrip menjalankannya dalam proses anak yang terpisah, yaitu, instance shell yang terpisah dipanggil untuk memproses skrip. Ini berarti bahwa variabel lingkungan apa pun, dll., yang ditentukan dalam skrip tidak dapat diperbarui di shell induk (saat ini).
Sumber skrip berarti diuraikan dan dieksekusi oleh shell saat ini sendiri. Seolah-olah Anda mengetik isi skrip. Karena alasan ini, skrip yang bersumber tidak perlu dapat dieksekusi. Tapi itu harus dapat dieksekusi jika Anda menjalankannya tentu saja.
Jika Anda memiliki argumen posisi di shell saat ini, argumen tersebut tidak akan berubah.
Jadi jika saya memiliki file a.sh
berisi:
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.
sumber pada dasarnya sama dengan mengetik setiap baris skrip di command prompt satu per satu...
Eksekusi memulai proses baru dan kemudian menjalankan setiap baris skrip, hanya mengubah lingkungan saat ini dengan apa yang dikembalikannya.