Shell komut dosyalarında exec komutunun kullanım alanları nelerdir?


250

Basit komutlarla kabuk komut dosyasında exec komutunun kullanımlarını açıklayan var mı?


31
Linux.about.com bağlantıları faydalı değildir. 'Exec' komutunu kullanarak bir komut veya komut satırını yürütmenin bunları normal olarak yürütmekten nasıl farklı olduğunu uzaktan netleştirmezler. Dolayısıyla OP'nin "exec kullanımı nedir" sorusu?
Jonathan Hartley

2
Stack Overflow, programlama ve geliştirme soruları için bir sitedir. Bu soru konu dışı gibi görünüyor çünkü programlama veya geliştirme ile ilgili değil. Yardım Merkezi'nde hangi konular hakkında soru sorabilirim konusuna bakın . Belki Süper Kullanıcı veya Unix & Linux Stack Exchange sormak için daha iyi bir yer olurdu.
jww

Yanıtlar:


281

execÇekirdekte yerleşik komut aynalar fonksiyonları dayalı onlardan bir aile vardır execvegenellikle C'den denir

execforkyeni bir işlem yapmadan, geçerli işlemde geçerli programı değiştirir . Yazdığınız her senaryoda kullanacağınız bir şey değildir, ancak bazen kullanışlı olur. İşte kullandığım bazı senaryolar;

  1. Kullanıcının kabuğa erişmeden belirli bir uygulama programını çalıştırmasını istiyoruz. / Etc / passwd içindeki oturum açma programını değiştirebiliriz, ancak belki ortam ayarının başlangıç ​​dosyalarından kullanılmasını istiyoruz. Yani, (örneğin) .profile, son ifade şöyle bir şey söylüyor:

     exec appln-program

    şimdi geri dönecek bir kabuk yok. Çöküyor olsa bile appln-program, son kullanıcı bir kabuğa ulaşamaz, çünkü orada değil - execonu değiştirdi.

  2. / Etc / passwd dosyasındakinden farklı bir kabuk kullanmak istiyoruz. Göründüğü kadar aptalca, bazı siteler kullanıcıların oturum açma kabuklarını değiştirmelerine izin vermez. Tanıdığım bir site herkesin başlamasını cshve herkesin .login(csh başlangıç ​​dosyasını) aramasını istedi ksh. Bu işe yaraırken, başıboş bir cshsüreç bıraktı ve çıkış, kafa karıştırıcı olabilecek iki aşamaydı. Bu yüzden exec kshc-shell programını korn kabuğu ile değiştirdik ve her şeyi daha basit hale getirdik (bunun kshbir giriş kabuğu olmadığı gerçeği gibi bununla ilgili başka sorunlar var ).

  3. Sadece süreçleri kurtarmak için. Biz ararsanız prog1 -> prog2 -> prog3 -> prog4vb ve asla geri, ardından her çağrı düzey yöneticisin olun. Kaynakları korur (tekrarlanana kadar, çok fazla değil, kuşkusuz) ve kapatmayı kolaylaştırır.

Belli bir execyerde kullanıldığını gördünüz , belki de hata yapan kodu gösterdiyseniz, kullanımını haklı çıkarabiliriz.

Düzenleme : Yukarıdaki cevabımın eksik olduğunu fark ettim. Kabuklarda ve - dosya tanımlayıcılarını açmak için kullanılan iki kullanım vardır . İşte bazı örnekler:execkshbash

exec 3< thisfile          # open "thisfile" for reading on file descriptor 3
exec 4> thatfile          # open "thatfile" for writing on file descriptor 4
exec 8<> tother           # open "tother" for reading and writing on fd 8
exec 6>> other            # open "other" for appending on file descriptor 6
exec 5<&0                 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4                 # copy write file descriptor 4 onto 7
exec 3<&-                 # close the read file descriptor 3
exec 6>&-                 # close the write file descriptor 6

Burada boşluk bırakmanın çok önemli olduğunu unutmayın. Eğer fd numarası ve yönlendirme sembolü arasına bir boşluk execyerleştirirseniz orijinal anlamı geri döner:

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

Birkaç Ksh kullanımına bu kullanabilirsiniz yolu vardır read -uveya print -uüzerinde, bashörneğin,:

read <&3
echo stuff >&4

22
aracılığıyla Genellikle WSGI web uygulamaları (Django söylemek veya şişeyi) çalıştırın Oldukça kullanışlı ve değer sizin (müthiş) arasında bir şey piton web uygulamaları ile ilgilidir ve görünüyor çünkü burada söz cevaplar 2 ve 3. Bulunan başka kullanımı da orada amir bir çağrıda gunicorn app: ikincisi oldukça az çevre değişkeni gerektiren, her şeyi ayarlayan ve sonunda exec gunicornsüpervizöre doğru pid'i veren bir kabuk betiğinden silahı çalıştırmak çok daha kolay ve daha sürdürülebilir .
gru

1
Dokümanlar böyle diyorsun execyönlendirme için kullanılabilir:> komut belirtilmemişse, herhangi yönlendirmeler geçerli kabuğunda etkili olması ve dönüş durumu 0 olan bir yönlendirme hatası varsa, dönüş durumu 1'dir Ama nasıl yapar execaslında bir dosya tanımlayıcı değiştirmek için çalışır? Bu özel komut neden bu görev için seçildi? (Markdown şu anda başarısız mı?)
Ray

@Ray: yapabileceğim en iyi şey: pubs.opengroup.org/onlinepubs/009604599/utilities/exec.html . Nasıl olduğunu bilmeniz gerekiyorsa, kabuk kaynak koduna bakın.
cdarke

7
Başka bir kullanım: Tüm komut dosyasının çıktısını bir günlük dosyasına yönlendirexec >.\logfilename.log 2>&1
Hogan

1
@Carmageddon: &>bir bashuzantıdır (bkz. man bash) Ve örneğiniz buna eşdeğerdir exec >/var/log/userdata.log 2>&1. Başka bir deyişle, stdout ve stderr dosyalarını bu dosyaya yönlendirir. Aşağıdaki komutlar sıfırlanmadıkça bu yönlendirmeleri devralır, ancak yürütülürler.
cdarke

41

Kabul edilen cevabı kısa bir acemi dostu kısa cevapla arttırmak için muhtemelen ihtiyacınız yoktur exec.

Hâlâ buradaysanız, aşağıdaki tartışma umarım nedenini açıklamalıdır. Koştuğunda söyle,

sh -c 'command'

bir shörnek çalıştırırsınız , ardından commando shörneğin alt öğesi olarak başlarsınız . Bittiğinde command, shörnek de biter.

sh -c 'exec command'

bir shörneği çalıştırır , ardından bu örneği ikili ile değiştirir ve onun yerine çalıştırır.shcommand

Elbette, her ikisi de bu sınırlı bağlamda işe yaramaz; sadece istiyorsun

command

Kabuğun yapılandırma dosyasını okumasını veya ortamı bir şekilde çalışmaya hazırlanmak için ayarlamasını istediğiniz bazı durumlar vardır command. exec commandYararlı olan tek durum budur.

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

Bu, gerekli olanı içerecek şekilde ortamı hazırlamak için bazı şeyler yapar. Bu yapıldıktan sonra, shörnek artık gerekli değildir ve bu nedenle , alt işlem olarak çalıştırmak ve beklemek, sonra biter bitmez çıkmak yerine shörneği basitçe commandişlemle değiştirmek (küçük) bir optimizasyondur sh.

Benzer şekilde, bir kabuk komut dosyasının sonundaki ağır komut için mümkün olduğunca fazla kaynak boşaltmak isterseniz, execbu komutu bir optimizasyon olarak kullanmak isteyebilirsiniz .

Şey güçlerinin Eğer çalıştırmak için shama sen gerçekten başka bir şey çalıştırmak istedim, exec something elseistenmeyen yerine ders geçici bir çözüm taşımaktadır shörneğin gerçekten kendi şık yapmak isterse gibi (örneğini goshyerine shama seninki yer almıyorsa /etc/shellsyapabilirsiniz böylece giriş kabuğunuz olarak belirtmeyin).

execDosya tanımlayıcılarını işlemek için ikinci kullanımı ayrı bir konudur. Kabul edilen cevap güzel bir şekilde bunu kapsar; bu müstakil tutmak için exec, bir komut adı yerine bir yönlendirme izleyen herhangi bir şey için el kitabına erteleyeceğim .


2
Kendi havalı kabuğunu çağırmak için günaha karşı koymak bush. Tabii ki, bu bashherhangi bir popüler Unix kabuğu için de veya genel olarak geçerlidir ; @anishsane notlarına göre , Bash bash -c 'command'bunu yaparak gizlice optimize eder exec command.
tripleee

1
Kabuğun çıkış kodu genellikle yürüttüğü son komutun çıkış kodudur. Elbette, kabuk çalışamazsa veya komutu yürütemezse, kabuğun çıkış durumu uygun bir hata koduyla bunu yansıtacaktır.
tripleee

2
@JonathanLeffler Kasten acemi sorularda gördüğüm bir karşıtlığı belgeliyorum. Bu, bu kopya tarafından istendi, ancak daha önce görmüştüm, bu yüzden özellikle bunu kapsamak istedim.
tripleee

2
@JonathanLeffler Küçük ifadeler tweak; bu yeterli mi sizce? Geri dönüşünüz için teşekkür ederiz.
tripleee

2
Teşekkürler - Bu optimizasyon hakkında kısa bir paragraf daha ekledim. Başka itirazlarınız varsa veya olayları farklı bir açıdan açıklamak istiyorsanız benim için gerçekten net değil.
tripleee
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.