A GUI file picker for bash in six lines of code

Note:

To make this work, your system needs three things:

  • Bash 4+
  • Python (with python defaulting to Python 2)
  • Tkinter

The first two are fulfilled out of the box on most modern Linux distributions, the last two are default in OS X. Therefore, on Linux you need to install Tkinter, while on OS X a recent version of Bash has to be installed (e.g. via Homebrew) because OS X still ships with Bash 3.2.

Note 2:

I am well aware that toucans have nothing to do with the content of this post, but I could not think of a tangible metaphor for shell scripting and I just love how these birds look :)

The ubiquitous and venerable Bash can be quite a flexible tool once one gets past its idiosyncratic scripting environment and many quirks. As an example of what is possible, add the following to your .bashrc (Linux) / .bash_profile (OS X):

select_files() {
  local files="$(python -c 'import Tkinter, tkFileDialog; Tkinter.Tk().withdraw(); print(" ".join(map(lambda x: "'"'"'"+x+"'"'"'", tkFileDialog.askopenfilename(multiple=1))))')"
  READLINE_LINE="${READLINE_LINE:0:READLINE_POINT}$files${READLINE_LINE:READLINE_POINT}"
  READLINE_POINT=$((READLINE_POINT + ${#files}))
}
bind -x '"\C-g":select_files'

From now on, whenever you are in a graphical terminal emulator typing a command, press Ctrl+G at any time to bring up a system file picker dialog supporting multiple selections which will insert the full paths of all files you picked right back into the command line you were working on! Python does the heavy lifting here, while Bash's readline features provide the glue that ties everything together. If X11 forwarding over SSH is enabled, this might even work for remote systems (not tested yet).

Note that changing the keyboard shortcut to something else is not as straightforward as it may seem. Many other key combinations can not be bound with the -x flag although workarounds do exist. Welcome to the weird and wonderful world of shell scripting...

Cover image: Olaf Oliviero Riemer (Wikimedia Commons, CC-BY-SA)