A Quick Fix'e kadar tamamen atlayabilirsiniz ancak bu mutlaka en iyi seçenek değildir. Bu yüzden önce bütün bunları okumanızı öneriyorum.
rc.local
hataları hoş görmez.
rc.local
hatalardan akıllıca kurtarmanın bir yolunu sağlamıyor. Herhangi bir komut başarısız olursa, çalışmayı durdurur. İlk satır, bayrakla #!/bin/sh -e
çağrılan bir kabukta yürütülmesine neden olur -e
. -e
Bayrak (bu durumda bir komut dosyası kılan rc.local
bir komut içindeki başarısız ilk kez yayından).
Böyle rc.local
davranmak istiyorsun . Bir komut başarısız olursa, do not diğer başlatma komutları başaran buna güvenerek olabilir ne olursa olsun devam etmek istiyorum.
Dolayısıyla herhangi bir komut başarısız olursa, sonraki komutlar çalışmayacaktır. Buradaki sorun, /script.sh
çalışmadı (başarısız oldu, aşağıya bakınız), bu yüzden büyük olasılıkla başarısız önce bazı komuttur. Fakat hangisi?
Öyle miydi /bin/chmod +x /script.sh
?
Yok hayır.
chmod
herhangi bir zamanda iyi çalışır. İçerdiği dosya sistemi /bin
monte edildiyse, çalıştırabilirsiniz /bin/chmod
. Ve çalıştırmadan /bin
önce monte edilir rc.local
.
Kök olarak çalıştırdığınızda, /bin/chmod
nadiren başarısız olur. Çalıştığı dosya salt okunur ise başarısız olur ve üzerinde çalıştığı dosya sistemi izinleri desteklemiyorsa başarısız olabilir . Burada da muhtemel değil.
Bu arada, başarısız olursa, aslında bir sorun olması sh -e
için tek nedeni budur chmod
. Bir script dosyasını tercümanını açık bir şekilde çalıştırarak çalıştırdığınızda, dosyanın çalıştırılabilir olarak işaretlenmesi önemli değildir. Yalnızca /script.sh
dosyanın çalıştırılabilir biti olacağı söylenirse . Diyor yana sh /script.sh
, öyle değil (tabii sürece /script.sh
kendisini çağıran o yürütülebilir olmama gelen başarısız olabilecek şekilde, ishal, ama buna kendisini çağıran düşüktür iken).
Peki ne başarısız oldu?
sh /home/incero/startup_script.sh
başarısız oldu. Neredeyse kesin.
Çalıştığını biliyoruz, çünkü indirildi /script.sh
.
(Aksi takdirde, durumunda her nasılsa, bu kaçtın emin olmak için önemli olacağını /bin
değildi PATH - rc.local
ille aynı bulunmamaktadır PATH
. Eğer giriş yaptığınızda olduğu gibi değilse /bin
değildi rc.local
'ın yolu, bu gerektirecektir sh
olarak çalıştırılacak /bin/sh
. çalıştırıyordu beri /bin
olduğu PATH
, yeralıyorsunuz diğer komutları çalıştırabilirsiniz yani /bin
tam isimlerini eleme olmadan. Örneğin, sadece çalıştırabilirsiniz chmod
ziyade /bin/chmod
. Ancak, tarzı doğrultusunda in rc.local
, sh
ne zaman çalıştırmanızı öneririm dışında , tüm komutlar için tam olarak nitelenmiş isimler kullandım .)
/bin/chmod +x /script.sh
Asla kaçmadığımızdan emin olabiliriz (ya /script.sh
da idam edildiğini göreceksiniz ). Ve biliyoruz ki sh /script.sh
kaçmadık.
Ama indirildi /script.sh
. Başardı! Nasıl başarısız olabilir?
Başarının İki Anlamı
Bir komutun başarılı olduğunu söylediğinde bir insanın ne anlama gelebileceği iki farklı şey vardır:
- İstediğini yaptı.
- Başardığını bildirdi.
Ve böylece başarısızlık için. Bir kişi bir komutun başarısız olduğunu söylediğinde, bunun anlamı olabilir:
- Yapmasını istediğin şeyi yapmadı.
- Başarısız olduğunu bildirdi.
sh -e
Like ile çalışan bir script , rc.local
bir komutun başarısız olduğunu bildirdiği ilk seferde çalışmayı durdurur . Komutun gerçekte yaptıkları arasında bir fark yoktur.
startup_script.sh
İstediğiniz şeyi yaptığında başarısızlık bildirme niyetinde değilseniz, bu bir hatadır startup_script.sh
.
- Bazı hatalar bir komut dosyasının yapmasını istediğiniz şeyi yapmasını önler. Programcının yan etkileri dediği şeyi etkiler .
- Bazı hatalar, bir betiğin başarılı olup olmadığını doğru şekilde bildirmesini engeller. Hangi programcıların dönüş değeri olarak adlandırdıklarını etkiler (bu durumda çıkış durumu ).
Başarısız olduğu bildirildi dışındastartup_script.sh
, yapılması gereken her şeyi yapmış olması muhtemel .
Başarı veya Başarısızlık Nasıl Bildirilir?
Bir komut dosyası, sıfır veya daha fazla komutun listesidir. Her komutun çıkış durumu vardır. Komut dosyasını çalıştırmada hiçbir başarısızlık olmadığını varsayarak (örneğin, tercüman komut dosyasını çalıştırırken bir sonraki satırı okuyamadıysa), bir komut dosyasının çıkış durumu şöyledir:
0
(basarili) eğer betik boştuysa (yani, komutları yoktu)
N
, komut dosyası komutun sonucunda sona erdiyse , bazı çıkış kodları nerededir.exit N
N
- Aksi takdirde, kodda çalışan son komutun çıkış kodu.
Bir çalıştırılabilir çalıştırıldığında, kendi çıkış kodunu bildirir - yalnızca komut dosyaları için değil. (Ve teknik olarak, komut dosyalarından çıkış kodları, onları çalıştıran mermilerin döndürdüğü çıkış kodlarıdır.)
Örneğin, bir Cı programı uçları ise exit(0);
, ya da return 0;
onun içinde main()
işlev kodu 0
(bu, örneğin, bir program çalıştırıldığı kabuk olabilir) süreci arama ortaya çıkarır, işletim sistemi, verilir.
0
programın başarılı olduğu anlamına gelir. Diğer her numara, başarısız olduğu anlamına gelir. (Bu şekilde, farklı sayılar bazen programın başarısız olmasının farklı nedenlerini ifade edebilir.)
Komutlar başarısız oldu
Bazen, programın başarısız olacağı niyeti ile çalışıyorsunuz. Bu durumlarda, programın başarısızlığı rapor ettiği bir hata olmasa da başarısızlığını başarı olarak düşünebilirsiniz. Örneğin, rm
zaten silinmediğinden emin olmak için mevcut olmadığını düşündüğünüz bir dosyayı kullanabilirsiniz .
Böyle bir şey, muhtemelen startup_script.sh
çalışmayı bırakmadan hemen önce oluyor . Vadede son komut komut muhtemelen başarısızlık bildiriyor (olsa bile onun "başarısızlık" tamamen ince ve hatta gerekli olabilir) komut rapor başarısızlık yapar.
Başarısız Olan Testler
Özel bir komut türü bir testtir , bunun anlamı yan etkilerinden ziyade dönüş değeri için bir komut çalıştırmak. Bir test, çıkış durumunun incelenebilmesi (ve buna göre harekete geçilmesi) için yürütülen bir komuttur.
Örneğin, 4'ün 5'e eşit olup olmadığını unuttuğumu varsayalım. Neyse ki, kabuk kodlamasını biliyorum:
if [ 4 -eq 5 ]; then
echo "Yeah, they're totally the same."
fi
Burada test [ -eq 5 ]
başarısız olur, çünkü sonuçta 4 ≠ 5 olur. Bu, testin doğru performans göstermediği anlamına gelmez; o yaptı. İş 4 = 5 olup olmadığını kontrol etmek, ardından öyleyse başarıyı bildirmek ve başarısız olmamaktır.
Görüyorsunuz, kabuk komut dosyasında, başarı aynı zamanda doğru , başarısızlık da yanlış anlamına gelebilir .
İfade echo
hiçbir zaman yayınlanmasa da, if
bir bütün olarak blok başarı ile sonuçlanır.
Ancak, daha kısa yazacağımı varsayalım:
[ 4 -eq 5 ] && echo "Yeah, they're totally the same."
Bu genel stenodur. &&
Bir olan boolean ve operatörü. Her iki taraftaki ifadelerden &&
oluşan bir ifade, &&
her iki taraf da doğru (başarılı) olmadıkça yanlış (başarısızlık) döndürür. Tıpkı normal bir ve .
Biri size sorarsa, "Derek alışveriş merkezine gidip bir kelebek düşündü mü?" Derek’in alışveriş merkezine gitmediğini biliyorsun, bir kelebek düşünürse, bunu anlamak zorunda değilsin.
Benzer şekilde, solundaki komut &&
başarısız olursa (yanlış), tüm &&
ifade hemen başarısız olur (yanlış). 'Nın sağ tarafındaki ifade &&
asla çalıştırılmaz.
İşte, [ 4 -eq 5 ]
koşuyor. "Başarısız" (yanlış döndürüyor). Yani tüm &&
ifade başarısız. echo "Yeah, they're totally the same."
asla kaçmaz. Her şey olması gerektiği gibi davrandı, ancak bu komut başarısızlık bildirir ( if
yukarıdaki eşdeğer şartların başarılı olduğunu bildirmesine rağmen ).
Eğer bir betiğin son ifadesi bu olsaydı (ve betiğin önündeki bir noktadan çıkmak yerine, betiği ele geçirirse), betiğin tamamı başarısız olur .
Bunun dışında pek çok test var. Örneğin, ||
("veya") ile yapılan testler vardır . Bununla birlikte, yukarıdaki örnek, hangi testlerin yapıldığını açıklamak için yeterli olmalı ve belirli bir ifadenin / komutun bir test olup olmadığını belirlemek için belgeleri etkin bir şekilde kullanmanızı mümkün kılmalıdır.
sh
vs. sh -e
, Tekrar Ziyaret Edildi
Yana hattı (ayrıca bkz bu soru üst kısmında) sahiptir bu komutla çağrılan sanki, işletim sistemi komut dosyasını çalıştırır:#!
/etc/rc.local
sh -e
sh -e /etc/rc.local
Buna karşılık, örneğin diğer komut, startup_script.sh
çalıştırmak olmadan-e
bayrak:
sh /home/incero/startup_script.sh
Sonuç olarak, içlerinde bir komut arızayı bildirdiğinde bile çalışmaya devam ederler.
Bu normal ve iyi. rc.local
ile çağrılması gereken sh -e
ve çoğu diğer komut - Çoğu komut dahil ederek koşmak rc.local
değil --should.
Sadece farkı hatırladığınızdan emin olun:
Komut dosyaları, sh -e
çıkış raporlama hatası ile çalıştırılır, içerdikleri bir komut raporlama hatasından çıkar.
Komut dosyası, &&
operatörler ile birleştirilmiş komut dosyasındaki tüm komutlardan oluşan tek bir uzun komut gibiydi .
sh
(With -e
) olmadan çalışan scriptler , onları sonlandıran (ondan çıkan) bir komut verene veya betiğin en sonuna kadar devam eder. Her komutun başarısı veya başarısızlığı esasen önemsizdir (bir sonraki komut kontrol etmediği sürece). Komut, son komut çalıştırmasının çıkış durumuyla çıkar.
Komut Dosyanızın Sonuçta Böyle Bir Hata Olmadığını Anlamasına Yardımcı Olma
Senaryonun olmadığında başarısız olduğunu düşünmesini nasıl önleyebilirsin?
Çalışmaya başlamadan hemen önce neler olduğuna bir bak.
Başarılı olması gereken bir komut başarısız olursa, nedenini anlayın ve sorunu düzeltin.
Eğer bir komut başarısız olduysa ve bu gerçekleşmesi gereken doğru şeyse, bu başarısızlık durumunun yayılmasını önleyin.
Bir hata durumunun yayılmasını engellemenin bir yolu, başarılı olan başka bir komutu çalıştırmaktır. /bin/true
Yan etkisi yoktur ve başarı bildirmez ( /bin/false
hiçbir şey yapmaz ve başarısız olur).
Başka bir komut dosyası tarafından sonlandırıldığından emin olmaktır exit 0
.
Bu mutlaka exit 0
senaryosun sonunda olduğu gibi değil . Örneğin if
, betiğin içinde çıktığı bir -block olabilir .
Betiğinizin başarısız olmasının nedenini, başarı raporunu vermeden önce bilmek en iyisidir. Eğer gerçekten bir şekilde başarısız oluyorsa (yapmak istediğini yapmamak anlamında), gerçekten başarısını rapor etmesini istemezsin.
Hızlı Düzeltme
Eğer yapamıyorsanız startup_script.sh
çıkış raporlama başarı, komutu değiştirebilirsiniz rc.local
o komut raporları başarı olsa böylece, o ishal o startup_script.sh
yoktu.
Şu anda var:
sh /home/incero/startup_script.sh
Bu komut aynı yan etkilere (yani koşmanın yan etkisi startup_script.sh
) sahiptir, ancak her zaman başarı bildirir:
sh /home/incero/startup_script.sh || /bin/true
Unutma, neden startup_script.sh
hata verdiğini bilmek ve düzeltmek daha iyidir .
Hızlı Onarım Nasıl Çalışır?
Bu aslında bir ||
test, bir veya test örneğidir .
Çöpü atıp atmadığımı ya da baykuşu fırçalayıp fırçalamadığımı sorduğunuzu varsayalım. Çöpü dışarı çıkarsaydım, baykuşu fırçalayıp fırçalamadığımı bile hatırlamamama rağmen "evet" diyebilirim.
Solundaki komut ||
çalışır. Başarılı olursa (doğru), sağ tarafın koşması gerekmez. Yani startup_script.sh
başarı rapor ederse , true
komut asla çalışmaz.
Ancak, eğer startup_script.sh
başarısızlık rapor ederse [çöpü dışarı çıkarmamışım] , o zaman /bin/true
[baykuşu fırçaladıysam] sonucu önemli.
/bin/true
(ya da her zaman başarıyı döndüren gerçek bazen dediğimiz gibi). Sonuç olarak, tüm komut başarılı olur ve bir sonraki komut rc.local
çalıştırılabilir.
Başarı / başarısızlık, doğru / yanlış, sıfır / sıfırdan başka bir not.
Bunu görmezden gelmekten çekinmeyin. Birden fazla dilde programlıyorsanız, bunu okumak isteyebilirsiniz (örneğin, sadece kabuk komut dosyası değil).
Kabuk kodlayıcıları C gibi programlama dillerini alan ve kabuk programcılığı alan C programcıları için, şunları bulmak için büyük bir karışıklık noktasıdır:
Kabuk komut dosyasında:
- Döndürme değeri
0
aracı başarı ve / veya gerçek .
- Başka bir şeyin dönüş değeri, başarısızlık ve / veya yanlış
0
anlamına gelir .
C programlamada:
- Döndürme değeri
0
aracı FALSE ..
- Dışında bir dönüş değeri
0
araçlarının gerçek .
- Neyin başarı, neyin başarısızlık olduğu konusunda basit bir kural yoktur. Bazen
0
başarı, bazen başarısızlık, bazen de yeni eklediğiniz iki sayının toplamının sıfır olduğu anlamına gelir. Genel programlamadaki dönüş değerleri, çok çeşitli farklı bilgi türlerini işaret etmek için kullanılır.
- Bir programın sayısal çıkış durumu, kabuk komut dosyası kurallarına uygun olarak başarı veya başarısızlık belirtmelidir. Yani,
0
C programınızda yanlış olsa bile , 0
başarılı olduğunu bildirmesini istiyorsanız (hangi kabuk daha sonra doğru olarak yorumlanırsa ) programınızın çıkış kodu olarak geri dönmesini sağlarsınız .