Gedit'in (ve diğer programların) terminalimde GTK uyarıları ve benzeri şeyler vermesini nasıl önleyebilirim?


32

Müthiş bir pencere yöneticisi baskınlıktan yükselttikten sonra güvenilir bir şekilde çalıştırıyorum. Masaüstü ortamım kasıtlı olarak çalışan tüm Gnome / Freedesktop servetlerine sahip değil - onları istemiyorum.

Böyle geditbir terminalden çalıştırdığımda :

gedit file

Girdiğimde veya kaydettiğimde veya başka durumlarda vesile olduğumda, terminalimin her yerine bunun gibi mesajlar çıkarır:

(gedit:5700): Gtk-WARNING **: Calling Inhibit failed: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files

Bu uyarının anlamını anlıyorum ve benim için önemli olmayacağına karar verdim.

Bu tür uyarıları nasıl kapatabilirim ? "Kapat" ifadesiyle, şu veya benzer geçici çözümlerden hiçbirini kastetmiyorum:

  • gedit çıkışını boruya aktarma /dev/null
  • gedit çıkışını yönlendiren bir sarmalayıcı komut dosyası yazma /dev/null
  • gedit çıktısını alan bir takma ad oluşturmak /dev/null

Bu geçici çözümler her Gnome uygulamasına ayrı ayrı uygulanmaları gerektiği için kabul edilemez - gedit terminali karıştırmayı seven tek kişi değildir.


2
Bahsettiğiniz 3 seçeneği neden kullanamıyorsunuz?
Tim

Bu uyarıları kapatabileceğinizi sanmıyorum, ancak @Tim'in sorduğu gibi, sorununuzu çözecek 3 seçeneği kullanmaya karşı neleriniz var?
ElefantPhace

7
Teşekkürler, kabuk yönlendirme nasıl yapılır biliyorum. Bunu yapmak istemememin nedeni (ve açıkça belirtin ki) bu uyarıların diğer birçok programda da ortaya çıkmasıdır. Dbus veya bu uyarıları üreten herhangi bir bileşen için bir yapılandırma seçeneği, onu oluşturan tüm programlar için uyarıyı kapatır . Yönlendirme ile, her bir program için ayrı ayrı geçici çözüm (bu bir çözüm değildir) uygulamak zorundayım.
FUZxxl

@ FUZxxl Hatalarımın tutarlı bir şekilde çıkmasına neden olamıyorum. Ama bir export GCONF_DEBUG="no"şey yaparsan merak ediyorum
Dan

@ dan08 Hayır, hile yapmak değil.
FUZxxl

Yanıtlar:


17

Birincisi, bu uyarıların kutusundan çıkmış bir Ubuntu'da görünmesini rahatsız edici buluyorum, bulabildiğim şeyleri devre dışı bırakmak için "uygun" bir yöntem yoktu (en yaygın "çözüm" ya kurmak. gir1.2-gtksource-3.0zaten kurulu olduğundan beri çalışmıyor gibi görünüyor ya da onları görmezden geliyorlar - ancak terminalimi gürültülü yaptıkları için tamamen bastırmak istiyorum).

Şu ana kadar tam olarak beklediğim gibi davrandığı görünen ve TuKsn'in cevabına dayanan ancak biraz daha da geliştiren şu kodla karşılaştım:

  • Varsayılan olarak ( gedit ...) F12 veya başka bir kısayol kullanmaya gerek kalmadan (filtre uygulanmamış kullanımı çağırmak için /usr/bin/gedit ...) çalışın .
  • Arka plan görevi olarak sonlandırıldığında girilen komut adını görüntüler.

Hala biraz genelleştirilebilir, ancak şimdilik, diğer komutlar için aynı işleme ihtiyaç duyuyorsanız gedit(), aynı filtreye ihtiyaç duyan diğer her bir komut adı için işlevi çoğaltın .

# solution adapted from: http://askubuntu.com/questions/505594
# TODO: use a list of warnings instead of cramming all of them to a single grep.
# TODO: generalize gedit() to allow the same treatment for several commands
#       without duplicating the function with only a different name
# output filter. takes: name_for_history some_command [arguments]
# the first argument is required both for history, but also when invoking to bg
# such that it shows Done <name> ... instead of e.g. Done /usr/bin/gedit ...
suppress-gnome-warnings() {
    # $1 is the name which should appear on history but is otherwise unused.
    historyName=$1
    shift

    if [ -n "$*" ]; then
        # write the real command to history without the prefix
        # syntax adapted from http://stackoverflow.com/questions/4827690
        history -s "$historyName ${@:2}"

        # catch the command output
        errorMsg=$( $* 2>&1 )

        # check if the command output contains not a (one of two) GTK-Warnings
        if ! $(echo $errorMsg | grep -q 'Gtk-WARNING\|connect to accessibility bus'); then
            echo $errorMsg
        fi
    fi
}
gedit() {
  suppress-gnome-warnings $FUNCNAME $(which $FUNCNAME) $@
}

Ve daha iyi bir versiyon (çok daha küçük, tamamen jenerik, olduğu gibi çağrıldığından beri geçmişi yeniden yazmaya gerek yok ve bütün çıktı yerine satır başına filtrelemek için daha iyi):

# generates a function named $1 which:
# - executes $(which $1) [with args]
# - suppresses output lines which match $2
# e.g. adding: _supress echo "hello\|world"
# will generate this function:
# echo() { $(which echo) "$@" 2>&1 | tr -d '\r' | grep -v "hello\|world"; }
# and from now on, using echo will work normally except that lines with
# hello or world will not show at the output
# to see the generated functions, replace eval with echo below
# the 'tr' filter makes sure no spurious empty lines pass from some commands
_supress() {
  eval "$1() { \$(which $1) \"\$@\" 2>&1 | tr -d '\r' | grep -v \"$2\"; }"
}

_supress gedit          "Gtk-WARNING\|connect to accessibility bus"
_supress gnome-terminal "accessibility bus\|stop working with a future version"
_supress firefox        "g_slice_set_config"

Bu harika bir cevap. Bunu gelecekte kullanacağım.
FUZxxl

2

Aynı zamanda geçici bir çözümdür, ancak bunu her uygulama için uygulamanıza gerek yoktur.

Bunu kendinize yazın .bashrcve uyarıları bastırmak için bu sarıcıyı F12 (veya başka bir anahtar seçti) ile kullanabilirsiniz:

# output filter
of() { 
    if [ -n "$*" ]; then   
        # write the real command to history without the prefix "of" 
        history -s "$*"

        # catch the command output
        errorMsg=$( $* 2>&1 )

        # check if the command output contains not a GTK-Warning
        if ! $(echo $errorMsg | grep -q 'Gtk-WARNING'); then
            echo $errorMsg 
        fi
    fi
}

# write the function "of" before every command if the user presses F12
bind '"\e[24~": "\e[1~ of \e[4~\n"'

Bu biraz daha iyi görünüyor. Bunu test edeceğim.
FUZxxl

1

Aslında, yukarıda gösterilen komut dosyasından çok daha kolay kullandığım C uyarıları gizleme aracını yazdım . Ayrıca, yazılı tüm çıktıyı yazacak stdout(GTK ve diğer uyarılar gönderilir çünkü varsayılan olarak stderrayrıştırmak yüzden stderrdeğil stdoutvarsayılan).

Yukarıdaki betiğin en büyük sorunlarından biri, regex ile eşleşmese bile, konsolunuza hiçbir şey yazmadığıdır. Bunun nedeni, tüm verileri bir değişkene kaydetmesi ve ardından bir kez yapılan değişkeni grep olarak göstermesidir. Ayrıca, çıktının muhtemelen çok fazla bellek kullanarak bu değişkende kaydedileceği anlamına gelir (en azından bunu geçici bir dosyaya kaydetmelisiniz.) Son olarak, görebildiğim kadarıyla grep, herhangi bir satırın eşleşmesi durumunda herhangi bir görüntüyü engelleyecektir. . Belki de tam olarak istediğini değil.

Araç, aşağıdaki gibi basit bir takma adla kullanılabilir:

alias gvim="hide-warnings gvim"

(Kullanıyorum gvim... Onunla da çalışacağına eminim gedit.)

Dosya kendi içindedir, C kütüphanesinden başka bir bağımlılık yoktur, böylece bir kopyasını alabilir ve kolayca derleyip kurabilirsiniz:

gcc hide-warnings.c -o hide-warnings
sudo cp hide-warnings /usr/bin/.

Dosyada başka belgeler de vardır ve --helphızlı belgeler için bir kez derlenmiş olarak kullanabilirsiniz .

Bir noktada, advgetopt kütüphanesinden faydalanacak olan yeni sürüm , C ++ dilindedir.


Bağlantı öldü.
Armin Rigo

@ArminRigo, Ah! Taşındı. Buraya taşınmadan önceki en yeni bağlantıyı verdim çünkü şimdi C ++. Ayrıca C ++ sürümüne bir bağlantı var. C versiyonu artık değişmeyecek.
Alexis Wilke

0

Bu tür bir sorunu çözmek için bir yardımcı program arıyordum, kendim.

Verilen cevaplarla ilgili sorunlarım aşağıdaki gibidir:

  • stdout ve stderr'in bir akışta toplanmaması önemlidir
  • Komutu çağıramaz, tüm çıktıyı sonlanana kadar filtreleyemem ve sonunda yazdıramam (yani çözüm çıktıyı düzgün bir şekilde yayınlamalıdır)
  • Stdout ve stderr mesajlarının sırasını olabildiğince korumak istiyorum

Bunu Bash ile yaparken yaptığım girişimleri takdir ediyorum, ancak yukarıda belirtilen tüm koşulların hepsini yerine getiren bir çözüm bulamadım.

Nihai çözümüm, birçok linux kutuya kurulmayacağını anladığım NodeJS'de yazılmış. JS sürümünü yazmayı seçmeden önce, onu python'da kodlamaya çalıştım ve async IO kütüphanesinin çok çirkin ve kırıldığını ve çok yeni python sürümlerine (~ BAZI yeni dağıtımlarda kullanıma hazır olan) kullanıldı.

Bağımlılıkları en aza indirgemek YALNIZCA python'u seçmekti, bu yüzden onu biraz düşük seviyeli, async odaklı IO için kayda değer bir kütüphane kümesine sahip olan NodeJS'den vazgeçtim.

İşte burada:

#!/usr/bin/env nodejs

const spawn = require('child_process').spawn

function usage() {
    console.warn('Usage: filter-err <error regex> <cmd> [<cmd arg> ...]')
    process.exit(1)
}

function main(err_regex, cmd_arr) {
    let filter = new RegExp(err_regex)

    let proc = spawn(cmd_arr[0], cmd_arr.slice(1), {
        shell: true,
        stdio: ['inherit', 'inherit', 'pipe']
    })

    proc.stderr.on('data', (err) => {
        err = err.toString('utf8')

        if (! err.match(filter))
            process.stderr.write(err)
    })

    proc.on('close', (code) => process.exit(code))
}

const argv = process.argv

if (argv.length < 4)
    usage()
else
    main(argv[2], argv.slice(3))

Bu betiği kullanmak için, bu satırları .bashrc dosyasına ekleyebilirsiniz:

alias gimp='filter-err "GLib-[^ ]*-WARNING" gimp'

Çalıştırmayı seçtiğiniz alt işlem stdin'i devralır, böylece BASH borularını veya yeniden yönlendirmeyi kullanabilirsiniz.

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.