[BR]: bash completion doesn't work on Debian
Environment:
- Fail2Ban version : v0.11.2, Debian package: fail2ban 0.11.2-2
- OS, including release name/version : Debian 11.5 bullseye
- [x] Fail2Ban installed via OS/distribution mechanisms
- [x] You have not applied any additional foreign patches to the codebase
- [x] Some customizations were done to the configuration (provide details below is so) as workaround to fix the issue
The issue:
Bash completion does not work in default installation on Debian OS.
Steps to reproduce
- Base default Debian installation with upgraded packages:
sudo apt update && sudo apt upgrade -y - Install bash-completion package:
sudo apt install -y bash-completion - Install fail2ban:
sudo apt install -y fail2ban
Expected behavior
When I type in console:
$ fail2ban-client <TAB><TAB>
I'm expecting the list of available fail2ban-client commands:
add echo get ping restart start stop version
banned flushlogs help reload set status unban
Observed behavior
Instead of the available commands list I get the list of of files in the current directory:
./ .a/ .bash_logout .config/ .profile
../ .bash_history .bashrc .lesshst
Issue investigation / Any additional information
It happens because of two points which details I'll describe below:
- bash-completion uses dynamic completion loading
- fail2ban package installs the one bash completion file
Some details...
-
bash-completion install base script
/usr/share/bash-completion/bash_completionwhich is auto loaded by .bashrc or /etc/profile.d/ 1.1. The script creates shell function __load_completion responsible for dynamic completion loading -
fail2ban package adds completion file during installation:
$ dpkg-query -L fail2ban | grep completion /usr/share/bash-completion /usr/share/bash-completion/completions /usr/share/bash-completion/completions/fail2ban -
When using
fail2ban-client <TAB><TAB>function __load_completion is trying to find and load completion file by command name -fail2ban-clientbut doesn't find it because [fail2ban] package completion file namedfail2ban3.1. Without proper completion file bash-completion provides default completion option - current directory listing.
Workaround or possible solution
Creation symbolic link during deb package installation fixes the issue:
sudo ln -s /usr/share/bash-completion/completions/fail2ban /usr/share/bash-completion/completions/fail2ban-server
sudo ln -s /usr/share/bash-completion/completions/fail2ban /usr/share/bash-completion/completions/fail2ban-client
sudo ln -s /usr/share/bash-completion/completions/fail2ban /usr/share/bash-completion/completions/fail2ban-regex
To verify the fix you have to logout/disconnect or remove remembered completion by firing:
$ complete -r fail2ban-client
$ complete -r fail2ban-server
$ complete -r fail2ban-regex
Sincerely, Ilya
Although we have indeed the bash-completion script, but its installation is rather a matter of maintainer for specific distribution and not provided in our repository at all.
However the registration which happens inside at the moment looks correct to me: https://github.com/fail2ban/fail2ban/blob/94dac78afebc2a4a676727527d99e70d970b061a/files/bash-completion#L182
@sylvestre any ideas what may be wrong there?
I have the same problem in the new version, but not in the old version. Because I found that the old version put the bash-completion file in the etc directory, while the new version puts it in the usr/share directory and is dynamically loaded. But dynamic loading requires the command to be the same as the file name, so fail2ban-client must be created manually. It has nothing to do with complete -F _fail2ban fail2ban-client fail2ban-server fail2ban-regex.
I just came across this "issue". And I'm slightly inclined to agree that it (the symlinking during installation) is indeed mostly a matter of maintainer for specific distribution. Though, granted fail2ban releases here are packaged as Debian packages which do include Bash completion file, I'd also agree that it may be reasonable to package symlinks for fail2ban-client, fail2ban-client, and fail2ban-server executables right into the release packages to reduce friction for consumers and maintainers. Thank you.
here is a simple script can fix it fix_fail2ban_completion.sh
#!/bin/bash
if [ -f "/usr/share/bash-completion/completions/fail2ban" ]; then
# Get the directory
dir="/usr/share/bash-completion/completions"
# List of links to create
links=("fail2ban-client" "fail2ban-server" "fail2ban-regex")
# Iterate through each link
for link in "${links[@]}"; do
# Check if symlink already exists
if [ ! -L "$dir/$link" ]; then
# Create symlink
ln -sf "$dir/fail2ban" "$dir/$link"
echo "Created symlink: $dir/$link -> $dir/fail2ban"
else
echo "Symlink already exists: $dir/$link"
fi
done
else
echo "File /usr/share/bash-completion/completions/fail2ban does not exist"
exit 1
fi