Bir segfaulting programından boru çıkışı


13

ttf2afmBazen segfaults ve bazen değil bir program (özellikle, tetex 3.0 parçası) çağıran bir komut dosyası var . İhtiyacım olan bilgiler her zaman bölümlere ayrılmadan önce yazdırılıyor , ancak program başarısız olduğunda boru yeniden yönlendirmesinin başarısız olmasını ve boruya hiçbir şey vermemesini durdurmakta zorlanıyorum.

Bir FIFO üzerinden yönlendirme denedim true, sonunda bir parantez içine alma , bir kabuk işlevinden yürütme ve encasing sh -c, ama komut dosyası hiç bir şey , yönlendirilmiş veya başka bir şekilde çıktı - stderr için bile izin vermiyor gibi görünüyor .

Çıktı yeteneğine sahip olduğunu biliyorum, komut satırından mükemmel bir şekilde verebileceği, ancak bir nedenle bir komut dosyasından değil.

Benim sorum şu, komut dosyası program segfaults gerçeği görmezden gelmek ve bana yine de çıktı vermek için herhangi bir yolu var mı?

BASH 4.1.10 (2) -çalışması yapıyorum.

Yanıtlar:


12

Programlar genellikle çıktılarını verimlilik için tamponlar. Yani, bir bellek alanında (tampon olarak adlandırılır) çıktı biriktirirler ve çıktıyı yalnızca tampon dolduğunda veya programdaki belirli anahtar noktalarda çıkarırlar. Program normal şekilde sona erdiğinde, çıktı arabelleğini temizler (yani içinde kalan tüm verileri yazdırır). Segmentlere ayrıldığında, arabellek içeriği kaybolur.

Programı doğrudan bir terminalde çalıştırırken bu etkiyi gözlemlemezsiniz, çünkü programın çıktısı bir terminale bağlandığında davranış farklıdır (normal bir dosyaya veya bir borunun aksine). Bir terminalde, varsayılan davranış her satırın sonunda arabelleği temizlemektir. Bu nedenle, program bölümlendiğinde noktaya kadar üretilen her tam satırı göreceksiniz.

Programı bir terminalde çalışmaya zorlayabilir ve çıktısını toplayabilirsiniz. En basit yol koşmaktır script. Üzerinde çalışmanız gereken birkaç sıkıntı var:

  • script konuşma metni dosyasına daha sonra kaldırmanız gereken bir başlık satırı ekler.
  • script komutun durum kodunu döndürmez, bu nedenle segfault veya başka bir hata hakkında bilgi edinmek istiyorsanız onu bir yere kaydetmeniz gerekir.
  • scriptnormal çıkış ve hata çıkışına neden olur; hata çıktısını ayrı bir dosyaya kaydetmeniz daha iyi olur.
export FONT="foo"
script -q -c '
    ttf2afm "$FONT.ttf" 2>"$FONT.ttf2afm-err";
    echo $? >"$FONT.ttf2afm-status"
' "$FONT.ttf2afm-typescript"
tail -n +2 <"$FONT.ttf2afm-typescript" >"foo.afm"
rm "$FONT.ttf2afm-typescript"
if [ "$(cat "$FONT.ttf2afm-status")" -ne 0 ]; then
  echo 1>&2 "Warning: ttf2afm failed"
  cat "$FONT.ttf2afm-err"
fi

Çıktı tamponunu 0'a ayarlayacak bir kabuk ayarı gibi daha zarif bir çözüm yok mu?
amfetamin

4

Sonunda bir deneme yanılma süreciyle anladım. Çözüm biraz kıvrıktır:

(trap 'true' ERR; exec ttf2afm "$FONT") |
grep ...

Görünüşe göre alt kabuk sürecini yakalanan hatayla devralma execnedenleri ttf2afm, segfault olup olmadığı önemli olmayan bir ortamda çalışmasına neden oluyor.

Her şey dahil ERRsinyali yakalamak, alt kabuğun ölmesini ve programın başarısız olması durumunda hemen sona erecek olan ana komut dosyasına bir sinyal göndermesini durduracaktır.

Tek sorun, işlem segfaults bir kez çekirdeğin bir yığın yığın izleme çöpünü doğrudan konsol cihazına vereceğidir , bu yüzden [bildiğim] çıktı alınmasını önlemenin bir yolu yoktur, ancak bu önemli değil stdout veya stderr'ı etkilemediğinden.


3
Bu sizin için işe yararsa sevindim, ancak bash'ın çıkış arabellek boyutunu 0 olarak ayarlaması nedeniyle çalışmamasının nedeninin güvenli olmadığını iddia edebilirim. Bash ttf2afmdoğrudan kullanılan tamponlamayı etkileyemez . Acaba nasıl (trap true ERR; exec ttf2afm "$FONT")| …farklı davranmayı başarıyor ttf2afm "$FONT" | ….
Gilles 'SO- kötü olmayı bırak
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.