Bash Tips: Autocompletion
By
Steer around errors and save yourself some typing by adding autocompletion to your Bash scripts.
The magic word that lets you reduce the number of key presses on the one hand and avoid the potentially fatal consequences of typos on the other is completion. There probably isn’t a command-line user alive today who doesn’t appreciate the Tab key, which completes commands at the start of the line as well as directory names and file names. However, quite a few people are probably blissfully unaware of the double-Tab shortcut – I mean Linux users who stand alone like a lighthouse in an ocean of Windows users. No kindred spirits will look over their shoulders and say: “There’s no need to type ls cd ls …; just type cd Tab-Tab instead, and the shell will show you a list!”
Completion isn’t a core feature of Bash, it’s part of the Readline library. The Readline complete() function triggers automatic completion of a text and is normally linked to the Tab key. Many programs use the Readline library, which explains why the completion mechanism is also available in these tools.
At the command line, the text in front of the cursor is decisive. If it starts with a dollar sign ($), Readline will search the list of variables; a tilde (~) triggers a search in the list of users defined in /etc/passwd, and a commercial at (@) searches in the list of hosts. Text without one of these special characters at the start of the line is interpreted by the completion mechanism as the start of the command – including aliases and shell functions. If nothing else is appropriate, Bash will try file name completion; that is, complete() will try to add the name of a file or directory in the current directory to the text.
To support all this completion, a number of Readline functions run in the background (e.g., complete-command, complete-filename, complete-into-braces, complete-username, complete-hostname, complete-variable). The command
bind -p | grep complete
shows Bash to which key this special feature is bound on the system. Tab is not the only key that triggers completion. Hostname completion can be very useful if you need hostname completion without the @, as in:
scp <file> <targ>Esc Ctrl+Al+Q
Bash then shows you the full name of the target computer:
scp <file> <targetcomputer>
The keyboard shortcut Esc Ctrl+Alt+Q (or M-@ if you have a meta key) is normally linked to complete-hostname and completes the initial characters of a hostname you are entering.
Beware of the Manual
Both hostname completion and user completion have a couple of pitfalls in store for the user. For example, Bash reads the hostname is from the file to which the HOSTFILE variable points. According to the Bash manual, if the HOSTFILE variable is set but empty, Bash will read from /etc/hosts. If the variable is not set, the completion list is empty.
But the Bash manual is wrong here; exactly the opposite is the case: The variable has to be either unset or list-filled with something – the HOSTFILE file doesn’t need to exist to use /etc/hosts as a source. In large environments /etc/hosts is typically empty anyway. In this case, every user can create their own HOSTFILE with their favorites and set the variable in ~/.bashrc.
User completion normally evaluates /etc/passwd. On networks that use a directory service to store usernames and rely on NSS-LDAP, Bash triggers an LDAP query for user completion. It can take ages; Bash appears to freeze. Depending on the size of the organization, a query like ~ Tab-Tab will return a huge number of usernames because it queries all of the users in LDAP! Unfortunately, no environmental variable equivalent to HOSTFILE exists for user completion in this case.
Your Own Completion
To extend the Bash completion system, you can use the built-in Bash complete command. The function isn’t exactly trivial, as you can easily see from the level of detail the man page provides. The easiest part is word completion. A small synchronization script that I wrote accepts a profile as its only argument,
complete -W “home data images baw” syncfiles
telling Bash to complete the possible profile names for the syncfiles command automatically when I press the Tab key. More powerful than -W is the -F option, which expects a shell function as an argument. From the current command line it computes the possible completions and stores them in the COMPREPLY array. Listing 1 shows an example, which I reduced significantly.
Listing 1: Completion with a Shell Function
001 #!/bin/bash 002 003 oocalc_complete() { 004 local ext="ods" 005 local word="$2" 006 007 # Standard completion (filename-completion) 008 local i=0 line 009 declare -a list 010 while read line; do 011 list[i++]="$line" 012 done < <(compgen -f -- "$word") 013 014 # Filter: only filenames with the correct extension 015 local w e 016 for w in "${list[@]}"; do 017 if [ -d "$w" ]; then 018 continue 019 else 020 e="${w##*.}" 021 if [ "$e" = "$ext" ]; then 022 COMPREPLY[i++]="$w" 023 fi 024 fi 025 done 026 } 027 028 complete -o plusdirs -F oocalc_complete oocalc
The current complete specification ensures that Bash only completes directories and ODS files for the oocalc command. First, in lines 8 through 12 the shell function creates a list of all files and directories that normal completion would cover. After this, the script filters out all the inappropriate directories and files. In line 22, valid completions are dumped into the COMPREPLY array, which is unfortunately necessary because the standard complete options, -X and -G, are only designed for filtering filenames and will not cooperate with autocompletion of directory names.
Do-it-Yourself Bash Bashing
Fortunately, the user does not have to type complete definitions for standard commands. For example, openSUSE installs an entire Complete framework. One alternative is the comprehensive bash-completion package, which completes all CLI options for GNU-compatible tools (Figure 1) and valid package names for the RPM command; it even knows the modules in CVS. If you want to tweak this yourself, you will find plenty of examples in the Bash Completion package.
Conclusions
Bash as a programming language gives users a sophisticated, but not entirely self-explanatory, tool. The autocompletion feature described here would suggest that the shell’s interactive mode has some very powerful functions up its sleeve. If you keep a small cheat sheet with the most important function keys next to your PC, you can substantially reduce the need to type.
The Author
Bernhard Bablok works for Allianz Managed Operations & Services SE, where he manages a large data warehouse comprising anything from mainframes to servers with technical performance measuring data. His hobbies are listening to music, riding his bike, and walking, but also Linux in general and object orientation specifically.
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Thousands of Linux Servers Infected with Stealth Malware Since 2021
Perfctl is capable of remaining undetected, which makes it dangerous and hard to mitigate.
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.