“Exec” komutu ne işe yarar?


108

Ben bash komutunu anlamıyorum exec. Ben (de görüldüğü gibi bir dosyaya tüm çıktıyı yönlendirmek için iç komut dosyalarını kullanılan gördük bu ). Ama nasıl çalıştığını ya da genel olarak ne yaptığını anlamıyorum. Adam sayfalarını okudum ama anlamıyorum.


Bir sürecin ne olduğunu biliyor musunuz ?
fkraiem

1
@fkraiem ne demek istiyorsun?
becko

Üzgünüm "ne" demek istedim. : p Ama cevap hayır gibi görünüyor.
fkraiem

Ama aslında senaryonuz execçok daha basit bir şekilde açıklanabilecek özel bir şekilde kullanıyor , bir cevap yazacağım.
fkraiem

Yanıtlar:


88

man bash diyor:

exec [-cl] [-a name] [command [arguments]]
      If command is specified, it replaces the shell.  No new  process
      is  created.  The arguments become the arguments to command.  If
      the -l option is supplied,  the  shell  places  a  dash  at  the
      beginning  of  the  zeroth  argument passed to command.  This is
      what login(1) does.  The -c option causes command to be executed
      with  an empty environment.  If -a is supplied, the shell passes
      name as the zeroth argument to the executed command.  If command
      cannot  be  executed  for  some  reason, a non-interactive shell
      exits, unless the execfail shell option  is  enabled.   In  that
      case,  it returns failure.  An interactive shell returns failure
      if the file cannot be executed.  If command  is  not  specified,
      any  redirections  take  effect  in  the  current shell, and the
      return status is 0.  If there is a redirection error, the return
      status is 1.

Son iki satır önemli olan şudur: Eğer tek execbaşına, komut olmadan çalıştırırsanız , yönlendirmelerin geçerli kabuğa uygulanmasını sağlar. Muhtemelen koşarken command > file, çıktısının uçbirim yerine yerine commandyazıldığını biliyorsunuzdur file(buna yeniden yönlendirme denir ). Eğer kaçarsan exec > fileyerine, o yönlendirme tüm kabuk için geçerlidir: kabuk tarafından üretilen herhangi bir çıktı yazılır fileyerine sizin terminaline. Örneğin burada

bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST

Önce yeni bir bashkabuk başlattım . Sonra, bu yeni kabukta çalışıyorum exec > file, böylece tüm çıktılara yönlendiriliyor file. Aslında, ondan sonra çalışıyorum dateama çıktı alamıyorum, çünkü çıktı yönlendirildi file. Sonra kabuğumdan çıkıyorum (böylece yönlendirme artık geçerli olmaz) ve daha önce koştuğum komutun fileçıktısını içerdiğini görüyorum date.


42
Bu sadece kısmi bir açıklamadır. execmevcut kabuk işleminin bir komutla değiştirilmesine de hizmet eder, böylece ebeveyn bir yol izler ve çocuğun parası vardır. Bu sadece yönlendirme için değil. Lütfen bu bilgiyi ekle
Sergiy Kolodyazhnyy

3
@ SergiyKolodyazhnyy'nin yorumunda, beni bu sayfaya yönlendiren yeni karşılaştığım örnek, bir docker-entrypoint.sh. Burada, nginx config üzerinde çeşitli işlemler yaptıktan sonra betiğin son satırı yer alıyor exec nginx <various nginx arguments>. Bu, nginx'in bash betiğinin pidini devraldığı anlamına gelir ve şimdi nginx, betiğin değil, kabın ana çalışan işlemidir. Sanırım bu sadece temizlik için, başkası bunun için daha somut bir neden bilmiyorsa?
Luke Griffiths,

1
@Luke Buna "sarmalayıcı komut dosyası" denir. Buna örnek olarak gnome-terminal, en azından 14.04'te, bağımsız değişkenleri ayarlamak için bir sarmalayıcı komut dosyası bulunan bir örnek de verilebilir. Ve bu onların tek amacı, gerçekten sanat ve çevre. Başka bir dava, temizlik yapmak - önce bir sürecin önceki örneğini öldürmek ve
yenisini

Başka bir execbenzer bir örnek nginx@LukeGriffiths tarafından verilen örnek bir ~/.vnc/xstartupkomut vncserverdaha sonra bir VNC sunucu işlemi ve yapılandırmak için kullanılır exec gnome-sessionya da exec startkdeve benzerleri.
Trevor Boyd Smith

@LukeGriffiths, execbir kapsayıcı başlangıç ​​komut dosyasındaki ana neden , kapsayıcının ENTRYPOINT adlı PID 1'in Docker'da özel bir önemi olması. Bu, sinyalleri alan ana bir süreçtir ve var olduğu zaman, konteyner de çıkar. Bu emir komuta zincirinden execçıkmanın shve arka planını, konteynerin ana süreci yapmanın bir yolu .
kkm

46

exec En az bir argümanın onunla kullanılmasına veya hiç bir argümanın kullanılmamasına bağlı olarak, iki farklı davranışlı bir komuttur.

  • En az bir argüman iletilirse, birincisi komut adı olarak alınır execve kalan argümanları bu komuta ileterek bir komut olarak çalıştırmayı ve varsa yönlendirmeleri yönetmeyi deneyin.

  • İlk argüman olarak iletilen komut mevcut değilse, yalnızca exec komutu değil, geçerli kabuk hatayla çıkar.

  • Komut varsa ve çalıştırılabilirse, geçerli kabuğun yerini alır. Bu exec, bir komut dosyasında görünürse, exec çağrısını izleyen yönergelerin hiçbir zaman yürütülmeyeceği anlamına gelir ( execkendisi bir kabuk altında değilse ). execasla geri dönmez. "EXIT" gibi Shell tuzakları da tetiklenmeyecek.

  • Herhangi bir argüman iletilmezse, execyalnızca geçerli kabuk dosyası tanımlayıcılarını yeniden tanımlamak için kullanılır. Kabuk exec, önceki durumdan farklı olarak devam eder , ancak standart girdi, çıktı, hata veya yönlendirilen herhangi bir dosya tanımlayıcısı etkinleşir.

  • Yönlendirmelerin bazıları kullanılırsa /dev/null, ondan herhangi bir giriş EOF değerini döndürür ve herhangi bir çıkış atılır.

  • -Örneğin, dosya tanımlayıcılarını kaynak veya hedef olarak kullanarak kapatabilirsiniz exec <&-. Daha sonra okumak ya da yazmak daha sonra başarısız olacaktır.

İşte iki örnek:

echo foo > /tmp/bar
exec < /tmp/bar # exec has no arguments, will only affect current shell descriptors, here stdin
cat # simple command that read stdin and write it to stdout

Bu komut dosyası "foo" ifadesini cat komutu olarak çıkarır, normal durumda olduğu gibi kullanıcı girdisini beklemek yerine, foo içeren / tmp / bar dosyasından giriş alır.

echo foo > /tmp/bar
exec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc command
cat

Bu komut dosyası gösterilecektir 4(/ tmp / bar'daki bayt sayısı) ve hemen biter. catKomut yürütülmez.


4
`Bazı eski yazılar hiç eskimez ... +1.
17'de Cbhihe

3
Yönlendirmelerin bazıları / dev / null kullanıyorsa, ilişkili dosya tanımlayıcısı kapatılır. Hayır, gerçekten / dan yönlendirme yapıyor /dev/null, bu yüzden hala başarılı ve geri dönüş EOF okuyor. close(2)Bir fd okuma / yazma sistem çağrılarının hatalara geri dönmesine neden olur ve bunu exec 2>&-örneğin ile yaparsınız .
Peter Cordes,

2
Kendiniz deneyin:: exec 3</dev/null; ls -l /proc/self/fdfd 3'ün salt okunur / dev / null'da açık olacağını unutmayın. Sonra tekrar kapatın exec 3<&-ve ls -l /proc/$$/fdkabuk işleminizin artık fd 3 olmadığını ( tekrar ile) görebilirsiniz . (stdin ile kapanış exec <&-senaryolarda faydalı olabilir, ancak etkileşimli olarak bu bir oturum kapatma.)
Peter Cordes

@PeterCordes Kesinlikle haklısın. Cevap güncellendi. Teşekkürler!
jlliagre

1
Bu cevap harika çünkü en çok oy alan cevabın iki kullanım execdurumunu sadece bir kullanım durumundan bahseder, diğer cevap ise g_p'nin diğer kullanım durumundan bahseder. Ve bu cevap böyle karmaşık bir konu için hoş ve özlü / okunabilir.
Trevor Boyd Smith,

33

Anlamak execiçin önce anlamanız gerekir fork. Kısa tutmaya çalışıyorum.

  • Yoldaki bir çatala geldiğinizde, genellikle iki seçeneğiniz vardır. Linux programları yoldayken bu çatala ulaşıp fork()sistem çağrısında bulunur.

  • Normal programlar, sisteminizde derlenmiş bir biçimde bulunan sistem komutlarıdır. Böyle bir program yürütüldüğünde, yeni bir işlem oluşturulur. Bu alt süreç ebeveyniyle aynı ortama sahiptir, sadece süreç ID numarası farklıdır. Bu işleme çatal denir .

  • Forking, mevcut bir sürecin yenisini başlatması için bir yol sağlar. Bununla birlikte, bir çocuk sürecinin ebeveyn süreciyle aynı programın parçası olmadığı durumlar olabilir. Bu durumda execkullanılır. exec çalışmakta olan işlemin içeriğini bir program ikili dosyasındaki bilgilerle değiştirir.
  • Çatallama işleminden sonra, yeni işlem verileriyle alt sürecin adres alanının üzerine yazılır. Bu sisteme bir exec çağrısı ile yapılır.

3
execBir komut dosyası çıktısını, yayınladığım bağlantıdaki gibi yeniden yönlendirebilir misiniz ?
becko

1
Bunu belirsiz buldum "Ancak, bir çocuk sürecinin ebeveyn süreciyle aynı programın parçası olmadığı durumlar olabilir"
cdosborn

6

Olarak bash, bunu yaparsanız help exec:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive shell exits, unless
    the shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

İlgili bit:

If COMMAND is not specified, any redirections take effect in the current shell.

execBir olan kabuk yerleşik bir kabuk eşdeğerdir, execailesine sistemine çağırır o G_P bahseder (ve kimin Elyordamsayfalarının okuma görünmektedir). Sadece vardır POSIX zorunlu hiçbir komut belirtilirse geçerli kabuğunu etkileyen işlevselliğini.

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.