Reputation: 159
I'm new on bash and I'm trying to write a bash script that will save user's input (some tags), to help this user I would like to allow completion based on my personal list of predefined tags only and not on the common TAB files completion (files names in the folder).
predefinedtags=(one two three four five)
echo "enter tags (separate multiple values by space)"
read -e tags
echo $tags
I would like that during the read
input the user can press TAB
to complete is word with the list of predefined tags. I thought it was an common question and method but I do not find a good way to do it. I found some posts that are a bit too complex for me and they seem to explain that is a not a so simple question. I don't even know if it's possible or not.
Changing tab-completion for read builtin in bash
bash and readline: tab completion in a user input loop?
Do you have any ideas ? Or there is maybe a completely different way to do it ? Thank you for your help.
Upvotes: 5
Views: 1997
Reputation: 2868
In the second part, there is a simple version.
Give this tested version a try:
#!/bin/bash --
reade () {
tmpdir=$(date "+/tmp/%Y%m%d%H%M%S$$")
mkdir "${tmpdir}"
for ptag in "${predefinedtags[@]}" ; do
touch "${tmpdir}"/"${ptag}"
done
readetags=$(cd "${tmpdir}" || printf "internal error" ; read -re usertags ; printf "%s" "${usertags}")
rm -rf "${tmpdir}" 2>/dev/null >/dev/null
eval "${1}"=\"\$\{readetags\}\"
}
predefinedtags=(one two three four five)
printf "enter tags (separate multiple values by space)\n"
reade tags
printf "%s\n" "${tags}"
It migth be seen as odd but it is fun ! (and checked with shellcheck)
It defines a new reade function which creates a temporary directory with a unique name, and one empty file for each elements in predefinedtags. It changes the current directory to the new temporary one and runs read -e .
The TAB
key will work as expected.
Finally the tags entered by the user are all assigned to tags
.
Beware to not insert tags with spaces or special chars like ', " (etc.) into predefinedtags.
second part
You might want to define a configuration
directory that would already contain empty files (the predifined tags) instead of creating and removing a temporary directory.
Replace /path/to/configuration
with real pathname of the configuration
directory in the script below:
#!/bin/bash --
printf "enter tags (separate multiple values by space)\n"
tags=$(cd /path/to/configuration || printf "internal error" ; read -re usertags ; printf "%s" "${usertags}")
printf "%s\n" "${tags}"
The test (where TAB key press is written):
$ ls configuration/
five four one three two
$ ./script.sh
enter tags (separate multiple values by space)
TAB
five four one three two
five ten
five ten
$ touch configuration/cat
$ ls configuration/
cat five four one three two
$ ./script.sh
enter tags (separate multiple values by space)
TAB
cat five four one three two
cat hello
cat hello
Upvotes: 2