How do I suppress GtkDialog warnings in zenity and yad using Bash redirection in a script?
I'm trying to suppress GtkDialog
warnings in zenity
and yad
:
$ zenity --error --text hello
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
Error redirection and filtering works:
$ zenity --error --text hello 2> >(grep -v GtkDialog >&2)
YEAH... Annoying warning message disappears!!
This can be placed in ~/.bashrc
for development work as answered here:
- How to make zenity “transient parent” warning disappear permanently (using function)
and here:
- How to make zenity “transient parent” warning disappear permanently (using alias)
When creating a script for others to use though, you don't want the burden of them changing their ~/.bashrc
.
I'm having trouble creating a typing shortcut for: 2> >(grep -v GtkDialog >&2)
to be used inside script.
For many reasons variable assignment GTK_SPAM="2> >(grep -v GtkDialog >&2)"
followed later by variable usage "$GTK_SPAM"
doesn't work.
alias zenity="zenity 2> >(grep -v GtkDialog >&2)"
before calling script works but, I can't use this within a script.
Using an array to hold the typing shortcut isn't working:
$ 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.
I found many excellent generic answers on word-splitting and parameters which should solve my problem but a specific syntax eludes me.
Any clues?
Solution 1:
I don't think syntax alone can help you here - because of the order in which the shell sets up redirections and expands variables. To give a very simple illustration:
$ arr=( ">" "/dev/null" )
$ set -x
$ echo foo "${arr[@]}"
+ echo foo '>' /dev/null
foo > /dev/null
i.e. everything has been expanded "correctly", but > /dev/null
has simply become a list of string arguments passed to echo
.
You could force evaluation using eval
:
$ eval echo foo "${arr[@]}"
+ eval echo foo '>' /dev/null
++ echo foo
but really it would be better to redirect the stream for the duration of your script using exec
:
exec 2> >(grep -v GtkDialog >&2)
or, if you want to be able to turn the filter off before the end of the script, then based on After using exec 1>file
, how can I stop this redirection of the STDOUT to file and restore the normal operation of STDOUT? it should be possible to do
exec 3>&2 2> >(grep -v GtkDialog >&2)
and then later
exec 2>&3 3>&-
to recover the duplicated stream.
Solution 2:
You can define and use aliases in your script if you set the expand_aliases
shell option, e.g.:
#!/bin/bash
shopt -s expand_aliases
alias zenity='zenity 2> >(grep -v GtkDialog >&2)'
…
Now every zenity
line behaves as if 2> >(grep -v GtkDialog >&2)
were added and you can disable this behaviour as usual by prepending a backslash or command
:
\zenity # and
command zenity
both ignore the alias.
Further reading
- Why doesn't my Bash script recognize aliases?
Solution 3:
You can use function in the script. zenity
and yad
have useful info in stdout, so I suggest to redirect just stderr to /dev/null
#/bin/bash
zen_nospam() {
zenity "$@" 2&>1 >(grep -v GtkDialog >&2)
}
zen_nospam --error --text hello
btw function can be defined in .bashrc if needed in command line, not script