Làm cách nào để ngăn chặn gedit (và các chương trình khác) xuất ra các cảnh báo GTK và tương tự trong thiết bị đầu cuối của tôi?


32

Tôi đang chạy trình quản lý cửa sổ tuyệt vời trên sự tin cậy sau khi đã nâng cấp từ hiếm. Môi trường máy tính để bàn của tôi cố tình không có tất cả các trình tiện ích Gnome / Freedesktop đang chạy - tôi không muốn chúng.

Khi tôi thực thi gedittừ một thiết bị đầu cuối như thế này:

gedit file

Nó xuất ra các thông báo như thế này trên tất cả các thiết bị đầu cuối của tôi bất cứ khi nào tôi nhấn enter hoặc lưu hoặc trong các dịp khác:

(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

Tôi hiểu ý nghĩa của cảnh báo này và tôi đã quyết định rằng nó không quan trọng với tôi.

Làm thế nào tôi có thể tắt loại cảnh báo này? Bằng cách "tắt", tôi không có nghĩa là bất kỳ cách giải quyết nào trong số này hoặc tương tự:

  • đường ống đầu ra của gedit vào /dev/null
  • viết một tập lệnh bao bọc đưa đầu ra của gedit vào /dev/null
  • tạo ra một bí danh dẫn đầu ra của gedit vào /dev/null

Các cách giải quyết này không được chấp nhận vì chúng phải được áp dụng riêng cho từng ứng dụng Gnome - gedit không phải là ứng dụng duy nhất thích làm rối thiết bị đầu cuối.


2
Tại sao bạn không thể sử dụng 3 tùy chọn bạn đã đề cập?
Tim

Tôi không nghĩ bạn có thể tắt những cảnh báo đó, nhưng như @Tim đã hỏi, bạn có gì để chống lại việc sử dụng 3 tùy chọn sẽ giải quyết vấn đề của bạn?
ElefantPhace

7
Cảm ơn, tôi biết làm thế nào để chuyển hướng vỏ. Lý do tại sao tôi không muốn làm điều này (và nói rõ rằng) là vì những cảnh báo này cũng xuất hiện trong nhiều chương trình khác. Tùy chọn cấu hình cho dbus hoặc bất kỳ thành phần nào tạo ra các cảnh báo này sẽ tắt cảnh báo cho tất cả các chương trình tạo ra nó. Với chuyển hướng, tôi phải áp dụng cách giải quyết (không phải là giải pháp) cho từng chương trình riêng lẻ.
FUZxxl

@FUZxxl Tôi không thể nhận được gedit của mình để xuất lỗi liên tục. Nhưng tôi tò mò liệu export GCONF_DEBUG="no"có làm được gì không
Dan

@ dan08 Không, không làm trò bịp.
FUZxxl

Câu trả lời:


17

Đầu tiên, tôi cũng thấy khó chịu khi những cảnh báo này xuất hiện trên Ubuntu ngoài luồng, không có phương pháp "thích hợp" để vô hiệu hóa chúng mà tôi có thể tìm thấy (có vẻ như "giải pháp" phổ biến nhất là cài đặt gir1.2-gtksource-3.0có vẻ như không hoạt động vì nó đã được cài đặt hoặc bỏ qua chúng - nhưng tôi muốn triệt tiêu chúng hoàn toàn vì chúng chỉ làm cho thiết bị đầu cuối của tôi ồn ào).

Tôi đã đưa ra đoạn mã sau đây dường như hành xử chính xác như tôi mong đợi, và dựa trên câu trả lời của TuKsn, nhưng tăng cường một chút để:

  • Làm việc theo mặc định ( gedit ...) mà không cần sử dụng F12 hoặc một số phím tắt khác (để gọi sử dụng chưa được lọc /usr/bin/gedit ...).
  • Hiển thị tên lệnh đã nhập khi nó kết thúc làm tác vụ nền.

Vẫn có thể khái quát một chút, nhưng hiện tại, nếu bạn cần xử lý tương tự cho các lệnh khác, hãy sao chép gedit()hàm cho mỗi tên lệnh khác cần cùng một bộ lọc.

# 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) $@
}

Và một phiên bản tốt hơn (cách nhỏ hơn, hoàn toàn chung chung, không cần phải viết lại lịch sử kể từ khi được gọi, và tốt hơn để lọc trên mỗi dòng thay vì toàn bộ đầu ra):

# 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"

Đây là một câu trả lời tuyệt vời. Tôi sẽ sử dụng điều này trong tương lai.
FUZxxl

2

Đây cũng là một cách giải quyết, nhưng bạn không phải áp dụng điều này cho mọi ứng dụng.

Viết thư này cho bạn .bashrcvà bạn có thể sử dụng trình bao bọc này với F12 (hoặc chọn một khóa khác) để chặn các cảnh báo:

# 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"'

Điều đó có vẻ tốt hơn một chút. Tôi sẽ kiểm tra điều đó.
FUZxxl

1

Tôi thực sự đã viết công cụ ẩn cảnh báo bằng C mà tôi thấy dễ sử dụng hơn nhiều so với đoạn script hiển thị ở trên. Ngoài ra, nó sẽ ghi tất cả các đầu ra được ghi stdouttheo mặc định (vì Gtk và các cảnh báo khác được gửi tới stderrđể nó phân tích cú pháp stderrkhông stdouttheo mặc định).

Một vấn đề lớn với kịch bản ở trên là nó sẽ không ghi bất cứ điều gì vào bảng điều khiển của bạn, ngay cả khi nó không khớp với biểu thức chính quy, cho đến khi hoàn thành. Điều này là do nó lưu tất cả dữ liệu trong một biến và sau đó grep biến đó sau khi thực hiện xong. Điều đó cũng có nghĩa là nó sẽ lưu đầu ra trong biến đó có thể sử dụng nhiều bộ nhớ (ít nhất là bạn nên lưu nó trong một tệp tạm thời.) Cuối cùng, từ những gì tôi có thể thấy, grep sẽ ngăn bất kỳ hiển thị nào nếu bất kỳ một dòng nào khớp . Có lẽ không chính xác những gì bạn muốn.

Công cụ này có thể được sử dụng trong một bí danh đơn giản như thế này:

alias gvim="hide-warnings gvim"

(Tôi sử dụng gvim... Tôi chắc chắn rằng nó cũng sẽ hoạt động với gedit.)

Tệp này được chứa độc lập, không phụ thuộc ngoài thư viện C, vì vậy bạn có thể lấy một bản sao và dễ dàng biên dịch và cài đặt nó:

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

Có một số tài liệu khác trong tệp và bạn có thể sử dụng --helpmột khi được biên dịch cho các tài liệu nhanh.

Phiên bản mới hơn , tại một số điểm sẽ sử dụng thư viện advgetopt, có trong C ++.


Liên kết đã chết.
Armin Rigo

@ArminRigo, À! Nó đã di chuyển. Ở đây tôi đặt một liên kết mới đến mới nhất trước khi nó được di chuyển bởi vì bây giờ nó là C ++. Ngoài ra còn có một liên kết đến phiên bản C ++. Phiên bản C sẽ không thay đổi nữa.
Alexis Wilke

0

Bản thân tôi đang tìm kiếm một tiện ích để giải quyết vấn đề này.

Các vấn đề của tôi với các câu trả lời được cung cấp như sau:

  • điều quan trọng là thiết bị xuất chuẩn và thiết bị xuất chuẩn không được tổng hợp thành một luồng
  • Tôi không thể gọi một lệnh, lọc tất cả đầu ra cho đến khi nó kết thúc và in nó ở cuối (tức là giải pháp phải truyền phát đầu ra đúng cách)
  • Tôi muốn duy trì thứ tự các thông điệp xuất chuẩn và báo lỗi tiêu chuẩn càng nhiều càng tốt

Tôi đánh giá cao những nỗ lực mà tôi đã thấy để làm điều này với Bash, tuy nhiên, tôi đã thất bại trong việc xác định một giải pháp đạt được cả 3 điều kiện được nêu ở trên.

Giải pháp cuối cùng của tôi được viết bằng NodeJS, mà tôi hiểu rằng sẽ không được cài đặt trên nhiều hộp linux. Trước khi chọn viết phiên bản JS, tôi đã thử viết mã bằng python và thấy thư viện IO async khá xấu và bị hỏng cho đến khi RẤT phiên bản gần đây của python (~ 3.5 có sẵn trên SOME distro mới hơn).

Giảm thiểu sự phụ thuộc là lý do DUY NHẤT để chọn python, vì vậy tôi đã từ bỏ nó cho NodeJS, nơi có một bộ thư viện đáng chú ý cho IO ở mức độ thấp, không đồng bộ.

Đây là:

#!/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))

Để sử dụng tập lệnh này, bạn có thể thêm các dòng này vào .bashrc:

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

Quá trình con bạn chọn để chạy sẽ kế thừa stdin, vì vậy bạn có thể tự do sử dụng các ống BASH hoặc chuyển hướng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.