Dosya, sistem tarafından tanınan yürütülebilir dosya türlerinden biri olmadığından ve bu dosyayı yürütme izniniz olduğunu varsayarsak, execve()sistem çağrısı genellikle ENOEXEC( yürütülebilir değil ) hatasıyla başarısız olur .
O zaman ne olacak komutu çalıştırmak için kullanılan uygulama ve / veya kütüphane fonksiyonudur.
Bu bir kabuk, execlp()/ execvp()libc işlevi olabilir.
Diğer uygulamaların çoğu, bir komut çalıştırdıklarında bunlardan birini kullanır. Örneğin system("command line"), genellikle shkomut satırını (yolu derleme zamanında belirlenebilen ( Solaris'te /bin/shvs gibi /usr/xpg4/bin/sh)) ayrıştırmaya çalışacak olan libc işlevi aracılığıyla bir kabuk çağıracaklar veya $SHELLkendi başlarına depolanan kabukları çağıracaklar. vionun ile !komuta veya xterm -e 'command line've diğer birçok komutları ( su user -ckullanıcının giriş kabuğu yerine çağıracağı $SHELL).
Genel olarak, başlamamış, sessiz bir metin dosyası #bir shkomut dosyası olarak kabul edilir . Hangi sholsa değişecektir.
execlp()/ execvp(), execve()döndükten ENOEXECsonra genellikle shonu çağırır . shBirden fazla standarda uygun olabildikleri için birden fazla standarda sahip sistemler shiçin tipik olarak derleme zamanında belirlenecektir (uygulamanın farklı bir yola işaret eden farklı bir kod bloğunu kullanarak execvp()/ execlp()bağlayarak sh). Örneğin, Solaris'te bu /usr/xpg4/bin/sh(standart, POSIX sh) veya /bin/sh(Solaris 10 ve daha eski sürümlerde Bourne kabuğu (antika kabuk), Solaris 11'de ksh93) olacaktır.
Mermiler söz konusu olduğunda, çok fazla varyasyon var. bashAT & T ksh(sürece bir alt işleminde, Bourne Kabuk tipik olarak komut kendilerini yorumlayacaktır execkullanılmıştır), bir simüle sonra execve()tüm unexported değişkenler ayarlanmadan olduğu,,,, her yakın-on-exec fds kapalı tüm özel tuzakları çıkarıldı takma adlar, işlevler ... ( bashkomut dosyasını shmodda yorumlar). yash(kendini çalıştırır sholarak argv[0]öylesine de shbunu yorumlamak mod).
zsh, pdksh, ashMerkezli kabukları tipik olarak çağırır sh(derleme zamanında olan tespit yol).
İçin cshve tcsh(ve shbazı erken BSD türevi), dosyanın ilk karakteri ise #, o zaman kendileri yorumlamak, ve çalıştırır shaksi. Bu yorum olarak cshtanıdı #ama Bourne kabuğu değil, bir shebang öncesi zaman geri gider , bu yüzden #bir csh komut dosyası olduğunu bir ipucu oldu.
fish(en azından sürüm 2.4.0), execve()başarısız olursa bir hata döndürür (komut dosyası olarak ele almaya çalışmaz).
Bazı kabuklar ( bashAT&T veya AT&T gibi ksh) ilk önce sezgisel olarak dosyanın bir komut dosyası olup olmadığını belirlemeye çalışır. Yani, ilk birkaç baytta bir NUL karakteri varsa, bazı kabukların bir komut dosyasını çalıştırmayı reddedeceğini görebilirsiniz.
Ayrıca execve(), ENOEXEC ile başarısız olursa, ancak dosyanın bir shebang hattı varsa, bazı kabukların bu shebang hattının kendilerini yorumlamaya çalıştığını unutmayın.
Birkaç örnek:
- Ne zaman
$SHELLolduğunu /bin/bash, xterm -e 'myscript with args'olacak myscripttarafından yorumlanır bashiçinde shmod. İle birlikte xterm -e myscript with args, xtermkullanacak execvp()böylece script tarafından yorumlanacaktır sh.
su -c myscriptSolaris 10 üzerinde nerede rootbireyin giriş kabuğu /bin/shve /bin/shBourne kabuğu olacak olan myscriptBourne kabuk tarafından yorumlanır.
/usr/xpg4/bin/awk 'BEGIN{system("myscript")'Solaris 10 üzerinde yorumlayacaktır /usr/xpg4/bin/sh(aynı /usr/xpg4/bin/env myscript).
find . -prune -exec myscript {} \;Solaris 10'da (kullanma execvp()) POSIX ortamında bile (bir uyum hatası) /bin/shbile yorumlanacaktır /usr/xpg4/bin/find.
csh -c myscriptcshile başlarsa #, shaksi takdirde yorumlayacaktır .
Sonuç olarak, nasıl ve ne tarafından çağrılacağını bilmiyorsanız, bu komut dosyasını yorumlamak için hangi kabuğun kullanılacağından emin olamazsınız.
Her durumda, read -pbir bashemin komut tarafından yorumlanır emin olmak isteyeceksiniz yüzden, -sadece sözdizimi bash(ve bu yanıltıcı önlemek .shuzantısı). bashYürütülebilir dosyanın yolunu biliyor ve kullanıyorsunuz:
#! /path/to/bash -
read -p ...
Yoksa denemek ve bir güvenebilirsiniz $PATHait arama bashçalıştırılabilir (varsayarak bashkullanılarak yüklenir):
#! /usr/bin/env bash
read -p ...
( envneredeyse her yerde bulunur /usr/bin). Alternatif olarak, POSIX + Bourne uyumlu yapabilirsiniz, bu durumda kullanabilirsiniz /bin/sh. Tüm sistemlerde bir /bin/sh. Bunların çoğunda (çoğunlukla) POSIX uyumlu olacak, ancak şimdi ve sonra bir Bourne kabuğu bulabilirsiniz.
#! /bin/sh -
printf >&2 'Enter a user name: '
read user
printf '%s\n' "$user"