Yanıtlar:
Kaynak bir komut dosyası komutları çalışır geçerli kabuk süreci.
Yürütme bir komut dosyası bir komutları çalıştırır yeni kabuk süreci.
Komut dosyasının, çalışmakta olan kabuğunuzdaki ortamı değiştirmesini istiyorsanız, kaynağı kullanın. aksi takdirde yürütme kullanın.
Hala kafanız karıştıysa, lütfen okumaya devam edin.
Yürütülecek sözdizimi ve kaynak sözdizimi hakkında bazı genel karışıklıkları netleştirmek için:
./myscript
Bu , dosyanın çalıştırılabilir olması ve geçerli dizinde bulunması şartıyla yürütülür myscript
. Baştaki nokta ve eğik çizgi ( ./
) geçerli dizini gösterir. Bu gereklidir, çünkü geçerli dizin genellikle değildir (ve genellikle olmamalıdır) $PATH
.
myscript
Dosya çalıştırılabilir ve içindeki bir dizinde bulunuyorsa bu işlem yürütülür .myscript
$PATH
source myscript
Bu kaynak olacaktır myscript
. Dosyanın çalıştırılabilir olması gerekmez, ancak geçerli bir kabuk betiği olmalıdır. Dosya geçerli dizinde veya içinde bir dizinde olabilir $PATH
.
. myscript
Bu da kaynak olacaktır myscript
. Bu "yazım" POSIX tarafından tanımlandığı şekliyle resmidir . Bash, noktaya source
bir takma isim olarak tanımlandı .
myscript.sh
Aşağıdaki içeriği dikkate alın :
#!/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
Önce betiği çalıştırmadan önce mevcut ortamı kontrol ederiz:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Değişken FOO
tanımlanmadı ve biz giriş dizinindeyiz.
Şimdi dosyayı çalıştırıyoruz :
$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Çevreyi tekrar kontrol edin:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Değişken FOO
ayarlanmadı ve çalışma dizini değişmedi.
Betik çıktısı açıkça değişkenin ayarlandığını ve dizinin değiştirildiğini gösteriyor. Daha sonra kontrol, değişkenin ayarlanmadığını ve dizinin değişmediğini gösterir. Ne oldu? Değişiklikler yeni bir kabukta yapıldı. Geçerli kabuk bir olurken yeni komut dosyasını çalıştırmak için kabuk. Komut dosyası yeni kabukta çalışıyor ve ortamdaki tüm değişiklikler yeni kabukta etkili oluyor. Senaryo tamamlandıktan sonra yeni kabuk imha edilir. Yeni kabukta çevreye yapılan tüm değişiklikler yeni kabukla imha edilir. Geçerli kabukta yalnızca çıktı metni yazdırılır.
Şimdi dosyayı kaynaklıyoruz :
$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Çevreyi tekrar kontrol edin:
$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir
FOO değişkeni ayarlanmıştır ve çalışma dizini değişmiştir.
Komut dosyasını kaynaklamak yeni bir kabuk oluşturmaz. Tüm komutlar geçerli kabukta çalıştırılır ve ortamdaki değişiklikler mevcut kabukta etkili olur.
Bu basit örnekte, çalıştırmanın çıktısının betiği almakla aynı olduğunu unutmayın. Bu mutlaka her zaman böyle değildir.
Aşağıdaki komut dosyasını düşünün pid.sh
:
#!/bin/sh
echo $$
(özel değişken $$
, geçerli çalışan kabuk işleminin PID'sine genişler)
İlk önce mevcut kabuğun PID'ini yazdırın:
$ echo $$
25009
Komut dosyasını kaynakla:
$ source pid.sh
25009
Komut dosyasını yürütün, PID’e dikkat edin:
$ ./pid.sh
25011
Tekrar kaynak:
$ source pid.sh
25009
Tekrar yürütün:
$ ./pid.sh
25013
Komut dosyasını çalıştırmanın aynı işlemle çalıştığını, komut dosyasını çalıştırmanın her zaman yeni bir işlem oluşturduğunu görebilirsiniz. Bu yeni işlem, betiğin çalıştırılması için oluşturulan yeni kabuktur. Komut dosyasını kaynaklamak yeni bir kabuk oluşturmaz ve bu nedenle PID aynı kalır.
Komut dosyasını hem kaynak hem de yürütme, komutları satır satır yazmışsınız gibi satır satır komutları çalıştırır.
Farklılıklar:
Komut dosyasının, çalışmakta olan kabuğunuzdaki ortamı değiştirmesini istiyorsanız, kaynağı kullanın. aksi takdirde yürütme kullanın.
Ayrıca bakınız:
source myscript.sh
ve arasında bir fark var mı . myscript.sh
?
Bir betiği çalıştırmak, onu ayrı bir alt süreçte çalıştırır, yani betiği işlemek için ayrı bir kabuk örneği çağrılır. Bu komut tanımlanan herhangi bir ortam değişkenleri, vb anlamına gelir olamaz üst (akım) kabuk olarak güncellenir.
Bir betiği kaynaklamak, mevcut kabuğun kendisi tarafından ayrıştırıldığı ve yürütüldüğü anlamına gelir. Senaryonun içeriğini yazmış gibisin. Bu nedenle, kaynak kodun çalıştırılmasının çalıştırılabilir olması gerekmez. Ama elbette yürütüyorsanız çalıştırılabilir olması gerekir.
Geçerli kabukta konumsal argümanlarınız varsa, bunlar değişmez.
Yani a.sh
içeren bir dosya varsa :
echo a $*
ve ben:
$ set `date`
$ source ./a.sh
Gibi bir şey alıyorum:
a Fri Dec 11 07:34:17 PST 2009
Buna karşılık:
$ set `date`
$ ./a.sh
bana verir:
a
Umarım yardımcı olur.
Sourcing aslında komut dosyasının her satırını komut isteminde birer birer yazmakla aynıdır ...
Yürütme yeni bir işlem başlatır ve ardından komut dosyasının her satırını çalıştırır, yalnızca geçerli ortamı döndürdüğü şekilde değiştirir.
Yukarıdakilere ek olarak, betiğin ./myscript
dosya myscript için yürütme izni gerektirdiği şekilde yürütülmesi, kaynak bulma için yürütme izni gerektirmez. Bu yüzden chmod +x myscript
daha önce gerekli değilsource myscript
bash myscript
.
Kaynaklama, kodda tanımlanan tüm ekstra değişkenleri alır.
Eğer konfigürasyonlarınız veya fonksiyon tanımlarınız varsa, kaynak yapmalı ve çalıştırmamalısınız. İnfazlar ebeveynlerin ortamından bağımsızdır.
Eğer doğru hatırlıyorsam, betiğin çalıştırılması, #!
komut dosyasındaki satırda çalıştırılabilir dosyayı çalıştırır (genellikle yeni bir kabuk başlatılır ve betiği olduğu gibi yeni kabuğa etkili bir şekilde ekler #!/bin/sh
);
oysa, betiğin kaynak kodlaması, mevcut kabuk ortamınızdaki her satırı çalıştırır; bu, mevcut kabuğunuzu değiştirmek için yararlıdır (örneğin, kabuk işlevlerini tanımlamak ve ortam değişkenlerini dışa aktarmak için bir yol sağlar).
source
Komut Resim komut yürütüldüğünde (çalıştırılabilir izni olan zorunlu değildir ) de mevcut ise, kabuk çevre ./
temin yürütür yürütülebilir bir komut dosyası yeni kabuk.
Ayrıca, bu cevabı örneğin kontrol edin: https://superuser.com/a/894748/432100