スクリプトで Bash リダイレクトを使用して、zenity および yad の GtkDialog 警告を抑制するにはどうすればよいですか?

スクリプトで Bash リダイレクトを使用して、zenity および yad の GtkDialog 警告を抑制するにはどうすればよいですか?

およびGtkDialogの警告を抑制しようとしています:zenityyad

$ zenity --error --text hello
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.

エラーのリダイレクトとフィルタリングは機能します:

$ zenity --error --text hello 2> >(grep -v GtkDialog >&2)

うん...煩わしい警告メッセージが消えます!!

~/.bashrcこれは、ここで回答されているように、開発作業のために配置できます。

そしてここ:

ただし、他の人が使用するためのスクリプトを作成する場合、他の人がスクリプトを変更する負担をかけたくないでしょう~/.bashrc


2> >(grep -v GtkDialog >&2)スクリプト内で使用する入力ショートカットを作成するのに問題があります。

多くの理由により、変数の割り当てGTK_SPAM="2> >(grep -v GtkDialog >&2)"の後に変数の使用が続くと"$GTK_SPAM"機能しません。

alias zenity="zenity 2> >(grep -v GtkDialog >&2)"スクリプトを呼び出す前には機能しますが、スクリプト内でこれを使用することはできません。

配列を使用して入力ショートカットを保持することはできません。

$ aGtkSpam=(2\> \>\(grep -v GtkDialog \>\&2\))

$ DumpArray "${aGtkSpam[@]}"
Array Elements:
0: 2>
1: >(grep
2: -v
3: GtkDialog
4: >&2)

$ zenity --error --text hello "${aGtkSpam[@]}"
This option is not available. Please see --help for all possible usages.

$ yad --text hello 2> >(grep -v GtkDialog >&2)

$ yad --text hello "${aGtkSpam[@]}"
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.

単語分割とパラメータに関する優れた一般的な回答をたくさん見つけました。すべき問題は解決しましたが、具体的な構文がわかりません。

何か手がかりは?

答え1

シェルがリダイレクトを設定し、変数を展開する順序があるため、構文だけではここでは役に立たないと思います。非常に簡単な例を挙げると、次のようになります。

$ arr=( ">" "/dev/null" )
$ set -x
$ echo foo "${arr[@]}"
+ echo foo '>' /dev/null
foo > /dev/null

つまり、すべてが「正しく」展開されていますが、> /dev/null単に に渡される文字列引数のリストになっていますecho

あなたできた力の評価には以下を使用しますeval:

$ eval echo foo "${arr[@]}"
+ eval echo foo '>' /dev/null
++ echo foo

しかし、実際には、スクリプトの実行中は次のようにストリームをリダイレクトする方がよいでしょうexec

exec 2> >(grep -v GtkDialog >&2)

または、スクリプトの終了前にフィルターをオフにしたい場合は、を使用した後exec 1>file、STDOUT のファイルへのリダイレクトを停止し、STDOUT の通常の動作を復元するにはどうすればよいですか?それは可能であるはずだ

exec 3>&2 2> >(grep -v GtkDialog >&2)

そしてその後

exec 2>&3 3>&-

重複したストリームを回復します。

答え2

シェル オプションを設定すると、スクリプト内でエイリアスを定義して使用できますexpand_aliases。例:

#!/bin/bash
shopt -s expand_aliases
alias zenity='zenity 2> >(grep -v GtkDialog >&2)'

これで、すべてのzenity行が追加されたかのように動作します。2> >(grep -v GtkDialog >&2)バックスラッシュまたは を先頭に追加することで、通常どおりこの動作を無効にすることができますcommand

\zenity        # and
command zenity

どちらもエイリアスは無視されます。

参考文献

答え3

スクリプト内で関数を使用できます。stdoutに有用な情報があるzenityのでyad、stderrだけをリダイレクトすることをお勧めします。/dev/null

#/bin/bash

zen_nospam() {
  zenity "$@" 2&>1 >(grep -v GtkDialog >&2)
}

zen_nospam --error --text hello

ところで、関数はスクリプトではなくコマンドラインで必要な場合は.bashrcで定義できます。

関連情報