Soru bash: kırmızı renkli baskı stderr


Bash ekran yapmak için bir yolu var mı stderr mesajlar kırmızı renkte mi?


99
2017-08-26 21:10


Menşei


Bash çıktısını asla renklendirmeyecek sanırım: bazı programlar bir şeyi ayrıştırmak isteyebilir ve renklendirmeler, kaçan dizilerle verileri bozar. Bir GUI uygulaması renkleri ele almalı, sanırım. - kolypto
Balázs Pozsár ile killdash9 cevabını birleştirmek net bir şekilde verir: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }  Bash ve zsh için çalışıyor. Bunu bir yanıt b / c itibarı olarak ekleyemezsiniz. - Heinrich Hartmann
Bunu yapmak için bash'ı değiştiren bir cevap bekliyorum. Her şeyden önce çözümler aslında stderr'i değiştirebilir ve hatta muhtemelen w.r.t. stderr'in tam bayt dizisi korunmuş olduğunda, şeyleri parçalayan stdout, örn. boruları. - masterxilo


Cevaplar:


command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)

84
2017-08-26 21:39



Harika! Ama ben bunu kalıcı hale getirmenin bir yolu olup olmadığını merak ediyorum :) - kolypto
Büyük bahşiş! Öneri: Ekleyerek >&2 hemen önce ; done), stderr için tasarlanan çıktı aslında stderr'e yazılmıştır. Programın normal çıkışını yakalamak istiyorsanız bu yardımcı olur. - henko
Aşağıdaki kullanır tputve bence biraz daha okunabilir: command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done) - Stefan Lasiewski
Her çıktı hattı için 2 aşamalı işlemlerin yürütülmesi hiç de şık değil. Belki de tput komutlarının çıktısını bir değişkende saklar ve her eko için bunları kullanırsanız. Ama sonra tekrar okunabilirlik gerçekten daha iyi değil. - Balázs Pozsár
Bu çözüm, boşlukları korumaz ama ben onun kısalığı için seviyorum. IFS= read -r line yardımcı olmalı ama yapmaz. Emin değilim neden. - Max Murphy


Yöntem 1: işlem değiştirme kullan:

command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)

Yöntem 2: bir bash komut dosyasında bir işlev oluşturun:

color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1

Bunu şöyle kullanın:

$ color command

Her iki yöntem de komutu gösterir stderr kırmızı.

2. yöntemin nasıl çalıştığına dair bir açıklama için okumaya devam edin. Bu komutun gösterdiği bazı ilginç özellikler var.

  • color()... - Renk denen bir bash fonksiyonu oluşturur.
  • set -o pipefail - Bu, çıkışı başka bir komuta aktarılan bir komutun hata dönüş kodunu koruyan bir kabuk seçeneğidir. Bu, dış kabuktaki pipefail seçeneğini değiştirmemek için parantezler tarafından oluşturulan bir alt kabukta yapılır.
  • "$@" - Argümanları yeni bir komut olarak işlevine yürütür. "$@" eşdeğerdir "$1" "$2" ...
  • 2>&1 - yönlendirir stderr komutunun stdout böylece olur sed'ler stdin.
  • >&3 - için kısa yol 1>&3, bu yönlendirir stdout yeni bir geçici dosya tanıtıcısına 3. 3 geri yönlendiriliyor stdout sonra.
  • sed ... - Yukarıdaki yönlendirmelerden dolayı, sed'ler stdin öyle mi stderr yürütülen komutun Fonksiyonu, her çizgiyi renk kodlarıyla kuşatmaktır.
  • $'...' Ters eğik çizgi karakterlerini anlamasına neden olan bir bash yapısı
  • .* - Tüm çizgi ile eşleşir.
  • \e[31m - Aşağıdaki karakterlerin kırmızı olmasına neden olan ANSI çıkış sırası
  • & - The sed Eşleşen dizgenin tamamına genişleyen karakteri (bu durumda tüm satır) değiştirin.
  • \e[m - Rengi sıfırlayan ANSI çıkış sırası.
  • >&2 - için kısa yol 1>&2, bu yönlendirir sed'ler stdout için stderr.
  • 3>&1 - Geçici dosya tanıtıcısını yeniden yönlendirir 3 geri stdout.

74
2018-04-23 20:53



+1 en iyi cevap! mutlak şekilde az! - muhqu
Harika cevap ve daha iyi bir açıklama - Daniel Serodio
Neden tüm ek yönlendirme yapmak gerekiyor? overkill gibi görünüyor - qodeninja
@qodeninja Açıklama, yönlendirme için bir amaç sağlar. Bunu yapmak için daha basit bir yol bulabilirseniz, onu görmek isterim! - killdash9
Çalışması için bir yolu var mı zsh? - Eyal Levin


Ayrıca stderred’e de göz atabilirsiniz: https://github.com/sickill/stderred


23
2017-12-13 21:40



Vay, bu yardımcı program harika, ihtiyaç duyacağı tek şey onu etkinleştirmek için daha fazla iş yapmak zorunda kalmadan, bir hat ile, tüm kullanıcılar için onu yükleyen bir apt deposu sahip olmaktır. - sorin
Ayrı bir terminalde bir derleme betiğiyle test ettiğimde iyi çalıştığı görüldü, ancak bunu global olarak kullanmakta tereddüt ediyorum ( .bashrc). Yine de teşekkürler! - Joel Purra
OS X El Capitan'da, bu çalışma şekli (DYLD_INSERT_LIBRARIES), SIP tarafından korundukları için sistem ikili dosyalarında "bozuk" durumda. Yani diğer cevaplarda verilen bash seçeneklerini kullanmak daha iyi olabilir. - hmijail
MacOS için @hmijail takip edin github.com/sickill/stderred/issues/60 Bu yüzden bir geçici çözüm bulabiliriz, kısmi bir zaten var ama birazcık buggy. - sorin


http://sourceforge.net/projects/hilite/


14
2017-08-26 21:18





Yapmanın bash yolu stderr sürekli kırmızı akışları yönlendirmek için 'exec' kullanıyor. Aşağıdakileri bashrc'e ekleyin:

exec 9>&2
exec 8> >(
    while IFS='' read -r line || [ -n "$line" ]; do
       echo -e "\033[31m${line}\033[0m"
    done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'

Daha önce bunu yazdım: STDOUT ve STDERR için yazı tipi rengi nasıl ayarlanır


11
2018-01-29 08:49



ilgili: unix.stackexchange.com/questions/367636/... - Blauhirn
Bu, en iyi cevaptır; kurulumu / sudo ayrıcalığı gerektirmeden uygulanması kolaydır ve tüm komutlara göre genelleştirilebilir. - Luke Davis
Ne yazık ki bu, komut zincirleme ile iyi çalışmaz (command && nextCommand || errorHandlerCommand). Hata çıkışı errorHandlerCommand çıktısından sonra gider. - carlin.scott
Aynı şekilde eğer ben source ~/.bashrc Bununla iki kez, terminalim temelde kilitlenir. - Dolph
@Dolf: Benim bashrc'de, bu kodun yeniden yüklenmesini önlemek için çevreyle ilgili bir ifade ile buna kolayca karşı koyarım. Aksi takdirde, sorun, yeniden yönlendirme zaten yapıldıktan sonra 'exec 9> & 2' yeniden yönlendirmesidir. Belki de> 2'nin başlangıçta nereye baktığını biliyorsanız, bunu sabit olarak değiştirin. - gospes


Balázs Pozsár'ın cevabını saf bash'da uygulayan bir sarmalayıcı senaryo yaptım. Çıktılarını renklendirmek için $ PATH ve prefix komutlarınıza kaydedin.


    #! / Bin / bash

    eğer [$ 1 == "- yardım"]; sonra
        echo "Bir komut yürütür ve oluşan tüm hataları renklendirir"
        echo "Örnek:` basename $ {0} `wget ..."
        echo "(c) o_O Tync, ICQ # 1227-700, tadını çıkarın!"
        0'dan çık
        fi

    # Tüm hataları yakalamak için Temp dosyası
    TMP_ERRS = $ (mktemp)

    # Komutu çalıştır
    "$ @" 2>> (satır okunurken; eko -e yapın "\ e [01; 31m $ line \ e [0m" | tee --append $ TMP_ERRS; done)
    EXIT_CODE = $?

    # Tüm hataları tekrar göster
    eğer [-s "$ TMP_ERRS"]; sonra
        echo -e "\ n \ n \ n \ e [01; 31m === ERRORS === \ e [0m"
        kedi $ TMP_ERRS
        fi
    rm -f $ TMP_ERRS

    # Bitiş
    EXIT_CODE çıkışından çık


7
2017-08-26 22:13



"| Tee ...", "bittikten" sonra konulduysa, bu daha verimli hale getirilebilir. - Juliano


Böyle bir işlevi kullanabilirsiniz


 #!/bin/sh

color() {
      printf '\033[%sm%s\033[m\n' "$@"
      # usage color "31;5" "string"
      # 0 default
      # 5 blink, 1 strong, 4 underlined
      # fg: 31 red,  32 green, 33 yellow, 34 blue, 35 purple, 36 cyan, 37 white
      # bg: 40 black, 41 red, 44 blue, 45 purple
      }
string="Hello world!"
color '31;1' "$string" >&2


3
2017-08-26 22:29



Sorunu ele alma. Stderr'i stdout'tan ayırmanın bir yolunu sunmadın, bu da O'nun ilgilendiği şey. - Jeremy Visser


O_o Tync'in betiğinin biraz değiştirilmiş bir sürümü var. OS X Lion için bu modları yapmak gerekiyordu ve bu mükemmel değil çünkü komut bazen sarılmış komuttan önce tamamlıyor. Bir uyku ekledim ama eminim daha iyi bir yol var.

#!/bin/bash

   if [ $1 == "--help" ] ; then
       echo "Executes a command and colorizes all errors occured"
       echo "Example: `basename ${0}` wget ..."
       echo "(c) o_O Tync, ICQ# 1227-700, Enjoy!"
       exit 0
       fi

   # Temp file to catch all errors
   TMP_ERRS=`mktemp /tmp/temperr.XXXXXX` || exit 1

   # Execute command
   "$@" 2> >(while read line; do echo -e "$(tput setaf 1)$line\n" | tee -a $TMP_ERRS; done)
   EXIT_CODE=$?

   sleep 1
   # Display all errors again
   if [ -s "$TMP_ERRS" ] ; then
       echo -e "\n\n\n$(tput setaf 1) === ERRORS === "
       cat $TMP_ERRS
   else
       echo "No errors collected in $TMP_ERRS"
   fi
   rm -f $TMP_ERRS

   # Finish
   exit $EXIT_CODE

1
2018-06-08 17:37