如何在腳本中使用 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

我認為僅語法無法幫助您 - 因為 shell 設定重定向和擴展變數的順序。舉一個非常簡單的例子:

$ 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

如果設定了 shell 選項,則可以在腳本中定義和使用別名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

您可以在腳本中使用函數。zenity並且yad在 stdout 中有有用的信息,所以我建議將 stderr 重定向到/dev/null

#/bin/bash

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

zen_nospam --error --text hello

如果需要在命令列而不是腳本中順便說一句,可以在 .bashrc 中定義函數

相關內容