Bash script to open or close gnome-terminal with a single keybinding 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 &amp;
    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.
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))