Docker giriş noktası betikleri için set -e ve exec “$ @” ne yapar?


95

Docker için birçok entrypoint.sh betiğinin şöyle bir şey yaptığını fark ettim:

#!/bin/bash
set -e

... code ...

exec "$@"

Ne set -eve ne exec "$@"için?


2
BashFAQ # 105'e bakın re: why set -e, elle yazılmış hata işlemeden çok daha fazla hataya açık kabul edilir. (Aceleniz varsa, aşağıdaki alıştırmalar için üstteki analojiyi atlayın).
Charles Duffy

Yanıtlar:


72

Temelde, iletilen tüm komut satırı argümanlarını alır entrypoint.shve bunları bir komut olarak çalıştırır. Niyet temelde "Bu .sh betiğindeki her şeyi yapın, ardından aynı kabukta kullanıcının komut satırından girdiği komutu çalıştırın".

Görmek:


1
Ayrıca exec "$@", şu anda çalışan işlemi, aktarılan bağımsız değişkenler için oluşturulan yeni işlemle değiştireceğini unutmayın . Docker sinyallemesi için önemli: stackoverflow.com/a/32261019/99717
Hawkeye Parker

35

set -eçalıştırılan herhangi bir komut sıfır olmayan bir çıkış koduyla çıktığında hemen çıkacak bir kabuk seçeneği ayarlar. Komut dosyası, başarısız olan komutun çıkış koduyla geri dönecektir. Bash man sayfasından:

set -e:

Bir boru hattı (tek bir basit komuttan oluşabilir), bir liste veya bir bileşik komut (yukarıdaki SHELL GRAMMAR'a bakın), sıfır olmayan bir durumla çıkarsa hemen çıkın. Başarısız olan komut bir süre veya anahtar sözcüğünden hemen sonra komut listesinin bir parçasıysa, if veya elif ayrılmış sözcükleri izleyen testin parçası, && veya || ile çalıştırılan herhangi bir komutun parçasıysa, kabuk çıkmaz list, son && veya || 'den sonra gelen komut dışında, bir ardışık düzen içindeki herhangi bir komut ancak sonuncusu veya komutun dönüş değeri! ile ters çevriliyorsa. Alt kabuk dışındaki bir bileşik komut, -e yoksayılırken bir komut başarısız olduğu için sıfır olmayan bir durum döndürürse, kabuk çıkmaz. Eğer ayarlanmışsa, ERR üzerinde bir tuzak, kabuk çıkmadan önce yürütülür.

Bileşik bir komut veya kabuk işlevi -e'nin göz ardı edildiği bir bağlamda yürütülürse, bileşik komut veya işlev gövdesi içinde yürütülen komutların hiçbiri -e ayarından etkilenmez, -e ayarlanmış olsa ve bir komut bir arıza durumu. Bir bileşik komut veya kabuk işlevi, -e'nin göz ardı edildiği bir bağlamda yürütülürken -e'yi ayarlarsa, bu ayarın bileşik komut veya işlev çağrısını içeren komut tamamlanana kadar herhangi bir etkisi olmaz.


exec "$@"genellikle giriş noktasını, ardından docker komutunu çalıştıran bir geçiş yapmak için kullanılır. Mevcut çalışan kabuğu "$@"işaret eden komutla değiştirecektir. Varsayılan olarak, bu değişken komut satırı argümanlarına işaret eder.

Giriş noktası giriş noktası.sh'ye işaret eden bir görüntünüz varsa ve konteynerinizi olarak docker run my_image server startçalıştırırsanız entrypoint.sh server start, bu konteynerde çalışmaya dönüşür. Exec satırında entrypoint.sh, pid 1 olarak çalışan kabuk, kendisini komutla değiştirecektir server start.

Bu, sinyal işleme için kritiktir. Kullanmadan exec, server startyukarıdaki örnekte başka bir pid olarak çalışacak ve çıktıktan sonra kabuk betiğinize döneceksiniz. Pid 1'deki bir kabuk ile, bir SIGTERM varsayılan olarak göz ardı edilecektir. Bu docker stop, konteynırınıza gönderilen zarif durdurma sinyalinin serversüreç tarafından asla alınmayacağı anlamına gelir . 10 saniye sonra (varsayılan olarak), docker stopzarif kapatmadan vazgeçer ve uygulamanızı çıkmaya zorlayacak bir SIGKILL gönderir, ancak potansiyel veri kaybı veya kapalı ağ bağlantıları söz konusu olduğunda, uygulama geliştiricileri sinyali aldıysa etrafına kodlama yapmış olabilir. Aynı zamanda, konteynerinizin durması her zaman 10 saniye süreceği anlamına gelir.

shiftVe gibi kabuk komutlarıyla set --, değerinin değiştirilebileceğini unutmayın "$@". Örneğin /bin/sh -c "...", docker'in kabuk sözdizimini aşağıdakiler için kullanıyorsanız görünebilecek komuttan kaldıran bir komut dosyasının kısa bir kısmı CMD:

# convert `/bin/sh -c "server start"` to `server start`
if [ $# -gt 1 ] && [ x"$1" = x"/bin/sh" ] && [ x"$2" = x"-c" ]; then
  shift 2
  eval "set -- $1"
fi

....

exec "$@"

1
Eskimetest işaret eden POSIX özelliklerine bakın -a. [ "$#" -gt 1 ] && [ "$1" = /bin/sh ]doğru x"$1"değişimdir (yalnızca eski olmayan sözdizimini kullanırken bilgisayar korsanlığına gerek yoktur ).
Charles Duffy

Ayrıca, dizginin shift 2; set -- $1nasıl evalayrıştırılacağıyla aynı şey değildir . /bin/sh -c 'printf "%s\n" "hello world" "goodbye world"'Somut bir test senaryosu istiyorsanız, düşünün ve Bash'in bir dizeyi bağımsız değişkenlere dönüştürürken tırnakları ayrıştırmadığını görün .
Charles Duffy

@CharlesDuffy, eskimiş seçeneğiyle ilgili ipucu için teşekkürler, eminim bu hatayı tekrar yapacağım, eski alışkanlıklar zor ölür. İle, evalyine /bin/sh -cde bunun dizedeki davranışını yansıtmasını istediğime inanıyorum , ancak bir şeyi kaçırıyorsam lütfen bana bildirin.
BMitch

30

set -e - herhangi bir komut başarısız olursa komut dosyasından çık (sıfır olmayan değer)

exec "$@"- giriş değişkenlerini yeniden yönlendirecek, burada daha fazlasını görün


"Giriş değişkenlerini yeniden yönlendirecek mi"? Eh? execkesinlikle yeniden yönlendirmeler yaptığı bir kullanım moduna sahiptir, ancak bu o mod değildir.
Charles Duffy
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.