Çalışırken bash betiği (.sh) dosyasını değiştirebilir miyim?


28

Sanırım script.shyürütmesi biraz zaman alan bir betiğim var. Ben yürütüyorum ./script.sh. Terminal penceresinde çalışırken dosyayı değiştiriyorum script.sh. Bunun çalışmakta olan işlem üzerinde bir etkisi olacak mı?

Değiştirdikten sonra değiştirilen dosyayı yürüttüm, şimdi iki çalışan işlemim var. Bu iyi mi?


Yanıtlar:


36

Komut dosyanızda değişiklik yaptığınızda, değişiklikleri diskte yaparsınız (sabit disk - kalıcı depolama); Komut dosyasını yürüttüğünüzde, komut dosyası belleğinize (RAM) yüklenir.

Böylece, komut dosyasında yaptığınız değişiklikler, çalışan komut dosyasını etkilemeyecek, bu değişiklikleri yapmadan önce yürüttüğünüz sürümü çalıştıracaktır.

Ancak, daha önce çalışan örneği sonlandırmadan, değiştirilmiş betiği tekrar yürüttüğünüzde, betiğin iki örneği olacaktır - biri betiği değiştirmiş, eskisi.

Komut dosyasının kullandığı ve değiştirdiği kaynakların çakışacağı konusunda uyarılırsınız. Örneğin, komut dosyasını kullanarak bir dosyayı değiştiriyorsanız, daha sonra çalışan komut dosyası o dosyayı yazmak için açamaz ve doğru şekilde yürütülemez.

Güncelleme: Beni Unix.stackexchange.com'da daha iyi bir cevaba işaret ettiğim için Kayıtlı Kullanıcı'ya teşekkür ederiz.

Komut dosyasının boyutuna ve söz konusu derleyici / tercümana bağlı olarak, komut dosyası kısmen / tamamen yüklenir. Bu nedenle, komut dosyası tam olarak yüklenmediyse, komut dosyanızda yaptığınız değişiklikler, komut dosyasının bir kısmı belleğe yüklendikten sonra çalışan örneğe yansıyacaktır.

Bu nedenle, şu anda tahmin edilemeyen çıktı için çalışmakta olan diskteki komut dosyanızı değiştirmeniz önerilmez: Önce çalışan örneği durdurun, sonra komut dosyanızı değiştirin ve sonra komut dosyasını yeniden çalıştırın.



@registereduser: oh evet, bu soru bana sadece OS derslerimi hatırlattı. Ellerimi masaüstüme
götürdüğümde cevabımı düzenleyeceğim (

Kısa senaryolar için problem olmaması gerektiğini düşünüyorum.
becko

1
Bunu bash v3.2.48 ile denediğimde ( buraya bakın ), satırın sonundan fazla tamponlamadı (ve komut dosyasını çalıştırırken değiştirdiğimde fena halde başarısız oldu). Sadece bash v4.3.0 ile tekrar test ettim ve tüm (kısa) betiği tamponladı. Yani ... belirli bir davranışa güvenmezdim.
Gordon Davisson

1
@RegisteredUser bash'ın tüm sürümleriyle değil - bağlantılı olduğum örneğe bakın.
Gordon Davisson

4

Diğer cevaplarda söylenmediğini düşündüğüm bir şey ekleyeceğim. Bunların çoğu dosyayı nasıl düzenlediğinize bağlıdır . Yapma echo "stuff" >filekabuk (başka örneği) dan gerçekten dosyanın üzerine olacaktır diye düşünüyorum. Ancak, örneğin, dosyayı düzenler emacsve sonra kaydederseniz , bu olmaz. Bunun yerine, editör eski dosyayı bir yedekleme adıyla yeniden adlandırır (belki önceki yedeği kaldırır) ve sonra değiştirilmiş arabellek içeriğini yeni bir dosya olarak (şimdi yayınlanmış) eski adıyla yazar . Komut dosyasını okuyan kabuk (veya diğer tercüman) dosyayı yalnızca bir kez kesinlikle açacağından, bundan sonra dosya adının bulunduğu yerden bağımsızdır, açılış sırasında dosya adıyla ilişkilendirilen fiziksel disk dosyasını (inode numarası ile tanımlanır) okumaya devam eder. Bu yüzden, betiği bloklar halinde okutsa bile (ki bu, tamponlanmış metin G / Ç kullanıyorsanız en kolay çözüm olacaktır), düzenlemenin değiştirmeyeceği düşünülen dosyanın eski örneğindeki satırları okumaya devam edecektir.


+1 Sublime Text'i editörüm olarak kullanıyorum. Dosyayı çok mu değiştirdiğini biliyor musun emacs?
becko

1
Pek çok editörün, yazma işlemi sırasında bir çökme olursa, metnin hiçbir tam sürümünün kalmayacağı riskini önlemek için yeniden adlandırma şeması kullanacağını düşünüyorum (yedek sürümleri tutmasalar bile). Editörünüzün davranışının ne olduğunu "ls -i" (inode numaralarını gösterir) ile kontrol edebilirsiniz.
Marc van Leeuwen

1

bunun güncellenmesi gerekiyor, yukarıdaki cevaplar şimdi yalnızca kısmen doğrudur:

bash'ın geçerli sürümüyle, diskteki bir betiği çalışırken değiştirmek, bash'ın değişiklikleri belleğe yüklemeye "basmaya" ve bunları çalışan betiğe almasına neden olacaktır. Değişiklikleriniz şu anda yürütülmekte olan satırdan sonra gelirse, yeni satırlar yüklenir ve yürütülür. Ancak, bu bash tarafından yapılan bir tahmindir ve doğru ya da yanlış olabilir.

Bunu yapmanın daha iyi yolu, aşağıdaki eylemler dizisidir: 1) betiği belleğe yükle 2) betiği diskten sil 3) önce disk sürümünü silerek diske yeni bir betiği yaz, bellek sürümü buna olan bağlantılarını kaybeder Böylece 3. adımda yeni bir sürüm tedarik ettiğinizde, yeni içerikleri bellek sürümüne yüklemek için bash denemesi yapılmayacaktır.


0

@ jobin'in cevabı genellikle doğrudur, ancak ne yapmak istediğinize bağlı olarak olabilecek bazı başka cevaplar ekleyeceğim.

Eğer betiği değiştirmek istiyorsanız ve güvenli olduğunu bilmek istiyorsanız, o zaman mevcut olanı değil yeni bir dosyaya yazmak istiyorsanız, Yeni dosya eskisinin bulunduğu yerde bulunabilir. Yeni sürümünüzü yeni bir dosyaya yazın ve daha sonra mveskisinin üzerine taşımak için kullanın . Değiştirilen dosya hala var, sadece dizine bağlı değil. Çalışan scriptiniz kullanmaya devam edebilir ve bu script kendi dosyasını kapattığında, sistem dosyayı güvenli bir şekilde temizleyebileceğini bilir (hemen veya daha sonra olsun).

Senaryonun senaryosundaki hareketini gerçekleştirmek istiyorsanız daha zor bir probleminiz var. Bence senaryonun koduna yazman gerekecek. Bash komut dosyaları sinyalleri işleyebilir (örneğin benzeri bir şeyi yakalayabilir kill -USR1 [pid]) ve bir komut dosyası daha sonra bazı kodları yeniden yükleyerek yanıt verebilir. Yani, belki de istediğine yakın bir işlevsellik elde edebilirsin, ama neyin peşinde olduğunu bilmeden, bunu yapmak için iyi bir neden göremiyorum ve bu karmaşık bir şey yapmak istersen, muhtemelen daha sofistike olmasını istediğinden şüpheleniyorum. bunu yapmak için programlama dili.

Akılda tutulan bir betiğin davranışını göz önünde bulundurmak istemiyorsanız, o zaman şansınız kalmaz. Herhangi bir programlama görevini imkansız olarak çağırmakta tereddüt ediyorum, ancak bu tür bir görev için kaynak ve becerilere sahipseniz, muhtemelen burada sormazsınız.

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.