5
\$\begingroup\$

I wanted to bind a single hot key to open and close gnome-terminal in a way similar to terminal emulators such as tilda or guake. I use Ubuntu, and have configured this script to be executed when I press the key F1

The script will focus or minimize the first gnome-terminal window that is running. If no gnome-terminal is running, it will start a new one and place it in the top half of the screen.

#!/bin/bash
# Bind this script to a keyboard shortcut to add "pull-down" behaviour to
# the Gnome terminal similar to guake or tilda
# It seems to work with gnome-terminal or xfce4-terminal
# I haven't tested any other terminal emulators
TERMINAL_EMULATOR=gnome-terminal
function main {
 if [[ -z $(terminal_process) ]]; then
 # no running terminal emulator
 # open new terminal at top of the screen
 $TERMINAL_EMULATOR --geometry 80x1+0+0 &
 win_id=$(get_terminal_window)
 # set initial width to 100% and height to 45%
 xdotool windowsize $win_id $(absolute_window_size 100 45)
 xdotool windowactivate $win_id
 else 
 win_id=$(get_terminal_window)
 if [[ $(xdotool getactivewindow) == $win_id ]]; then
 # if terminal window is active, mimize
 xdotool getactivewindow windowminimize
 else
 # if terminal window is inactive, bring in focus
 xdotool windowactivate $win_id
 fi
 fi
}
function terminal_process {
 # Is gnome-terminal already running
 echo $( ps aux | grep $TERMINAL_EMULATOR | grep -v grep)
}
function get_terminal_window {
 # get id of open terminal window. Will wait for window to open if neccessary
 echo $(xdotool search --onlyvisible --sync --limit 1 --class $TERMINAL_EMULATOR)
}
function absolute_window_size {
 # convert relative window size to absolute pixel size, based on screen res
 width_percent=1ドル
 height_percent=2ドル
 IFS=x
 screen_dimensions=$(xrandr | grep connected | grep -o '[1-9]\+x[0-9]\+')
 set $screen_dimensions
 echo $(($width_percent*1ドル/100)) $(($height_percent*2ドル/100))
}
main

As someone coming from python, bash feels quite unfamiliar, and I would like some feedback on whether this script follows best practices. I also wonder if there's anything that can be simplified without losing readability.

janos
113k15 gold badges154 silver badges396 bronze badges
asked Feb 4, 2016 at 20:56
\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

Instead of this:

function terminal_process {
 # Is gnome-terminal already running
 echo $( ps aux | grep $TERMINAL_EMULATOR | grep -v grep)
}

You don't need the echo, you can let the standard output simply go through:

terminal_process() {
 # Is gnome-terminal already running
 ps aux | grep $TERMINAL_EMULATOR | grep -v grep
}

The same goes for get_terminal_window too.

Notice that I also changed the wording style of the function definition. This is the recommended style in bash, I suggest to apply this to all your functions.


You can actually go even further. [[ -z $(terminal_process) ]] is actually a text comparison, checking if the output of the command as a string is empty. Instead of that, it would be better to use the exit code of the function, like this:

if ! terminal_process; then
 # ...

This works, because the exit of grep will be success (= 0) if it matched something (process exists), and failure (non-zero) if it didn't match.

However, when using the function like this, since the output of grep is not captured within a $(...), it will be printed on stdout, which you probably want to avoid. You can easily suppress that by adding the -q flag:

terminal_process() {
 # Is gnome-terminal already running
 ps aux | grep $TERMINAL_EMULATOR | grep -qv grep
}

This can also be simplified:

echo $(($width_percent*1ドル/100)) $(($height_percent*2ドル/100))

Like this:

echo $((width_percent * 1ドル / 100)) $((height_percent * 2ドル / 100))
answered Feb 4, 2016 at 23:53
\$\endgroup\$
2
  • \$\begingroup\$ Will $(function_call), catch everything that goes to stdout in the function? \$\endgroup\$ Commented Feb 5, 2016 at 8:12
  • 1
    \$\begingroup\$ Yes it will. But actually I added an even better solution that doesn't need stdout at all, see my updated answer. \$\endgroup\$ Commented Feb 5, 2016 at 8:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.