터미널에서 GTK 경고 등이 출력되지 않도록 gedit (및 기타 프로그램)를 중지하는 방법은 무엇입니까? 경우에 터미널에

난폭에서 업그레이드 한 후 멋진 창 관리자를 신뢰할 수있게 실행하고 있습니다. 데스크탑 환경에 의도적으로 모든 Gnome / Freedesktop 데몬이 실행되고 있지는 않습니다. 원하지 않습니다.

다음 gedit과 같은 터미널에서 실행할 때 :

gedit file

입력하거나 저장하거나 다양한 경우에 터미널에 다음과 같은 메시지를 출력합니다.

(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

나는이 경고의 의미를 이해하고 그것이 중요하지 않다고 결정했습니다.

이런 종류의 경고를 려면 어떻게 해야합니까? “끄기”는 다음과 같은 해결 방법을 의미하지 않습니다.

  • gedit의 출력을 /dev/null
  • gedit의 출력을 파이프하는 래퍼 스크립트 작성 /dev/null
  • gedit의 출력을 파이프로 연결하는 별명 작성 /dev/null

이러한 해결 방법은 각 Gnome 응용 프로그램에 개별적으로 적용해야하므로 허용되지 않습니다. gedit만이 터미널을 엉망으로 만드는 것이 아닙니다.



답변

첫째, 나는이 경고가 즉시 사용할 수있는 우분투에 표시되는 것을 성가 시게합니다. gir1.2-gtksource-3.0이미 설치되어 있거나 무시하기 때문에 작동하지 않는 것 같습니다.하지만 터미널을 시끄럽게 만들기 때문에 완전히 억제하고 싶습니다.)

나는 지금까지 내가 예상했던 것과 정확히 똑같이 행동하는 것으로 보이며 TuKsn의 답변을 기반으로하지만 다음과 같이 조금 향상되었습니다.

  • gedit ...필터링되지 않은 사용을 호출하기 위해 F12 또는 다른 바로 가기를 사용할 필요없이 기본적으로 작동합니다 ( /usr/bin/gedit ...).
  • 백그라운드 작업으로 종료 될 때 입력 한 명령 이름을 표시합니다.

여전히 일반화 할 수 있지만 다른 명령에 대해 동일한 처리 gedit()가 필요한 경우 동일한 필터가 필요한 다른 명령 이름에 대해 함수를 복제하십시오 .

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

그리고 더 나은 버전 (더 작고, 완전하고, 호출 된 이후 히스토리를 다시 쓸 필요가 없으며, 전체 출력이 아닌 라인 당 필터링에 더 좋습니다) :

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


답변

또한 해결 방법이지만 모든 응용 프로그램에 적용 할 필요는 없습니다.

이것을 당신에게 쓰면 .bashrc경고를 억제하기 위해 F12와 함께이 래퍼를 사용하거나 다른 키를 선택할 수 있습니다.

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


답변

실제로 C로 숨겨진 경고 도구 를 작성했는데 위의 스크립트보다 사용하기가 훨씬 쉽습니다. 또한 stdout기본적으로 작성된 모든 출력을 기록합니다 (Gtk 및 기타 경고가 전송 stderr되므로 기본적으로 구문 분석 stderr되지 않기 때문에 stdout).

위의 스크립트에서 큰 문제 중 하나는 정규식과 일치하지 않아도 완료 될 때까지 콘솔에 아무것도 쓰지 않는다는 것입니다. 모든 데이터를 변수에 저장 한 다음 해당 변수를 한 번만 grep하기 때문입니다. 또한 많은 메모리를 사용하여 해당 변수에 출력을 저장합니다 (적어도 임시 파일에 저장해야 함). 마지막으로 볼 수 있듯이 grep은 한 줄이 일치하면 표시를 방지합니다 . 아마 당신이 원하는 것이 아닐 수도 있습니다.

이 도구는 다음과 같은 간단한 별칭으로 사용할 수 있습니다.

alias gvim="hide-warnings gvim"

(저는 gvim… 사용 gedit하기도합니다.)

파일은 자체 라이브러리에 있으며 C 라이브러리 외에 다른 종속성이 없으므로 사본을 가져 와서 쉽게 컴파일하고 설치할 수 있습니다.

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

파일에 몇 가지 추가 문서가 있으며 --help빠른 문서를 위해 컴파일 된 후에 사용할 수 있습니다 .

advgetopt 라이브러리를 사용하는 최신 버전 은 C ++에 있습니다.


답변

나는 이런 종류의 문제를 해결할 유틸리티를 찾고있었습니다.

제공된 답변에 대한 내 문제는 다음과 같습니다.

  • stdout과 stderr이 하나의 스트림으로 집계되지 않는 것이 중요합니다.
  • 명령을 호출하고 모든 출력을 종료 할 때까지 필터링 한 후 끝에서 인쇄 할 수 없습니다 (예 : 솔루션에서 출력을 올바르게 스트리밍해야 함)
  • stdout 및 stderr 메시지의 순서를 최대한 유지하고 싶습니다.

Bash 로이 작업을 시도한 것을 보았지만 위에서 설명한 세 가지 조건을 모두 달성 한 솔루션을 찾지 못했습니다.

내 궁극적 인 솔루션은 NodeJS로 작성되었으며 많은 Linux 상자에는 설치되지 않을 것입니다. JS 버전을 작성하기 전에 파이썬으로 코드를 작성하려고 시도했으며 비동기 IO 라이브러리가 매우 최신 버전의 파이썬 (~ 3.5는 일부 최신 배포판에서 즉시 사용할 수 있음)까지 꽤 추악하고 깨졌습니다.

의존성을 최소화하는 것이 파이썬을 선택하는 유일한 이유 였으므로 NodeJS에서는 포기했습니다. NodeJS에는 다소 저수준의 비동기 지향 IO를위한 뛰어난 라이브러리 세트가 있습니다.

여기있어:

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

이 스크립트를 사용하려면 .bashrc에 다음 줄을 추가하십시오.

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

실행하도록 선택한 하위 프로세스는 stdin을 상속하므로 BASH 파이프 또는 리디렉션을 자유롭게 사용할 수 있습니다.


답변