Suppose I have a bash function specialcat that cats a file in the ~/Special directory

specialcat () {
    cat ~/Special/$1

Suppose the ~/Special directory was set up like so:

mkdir ~/Special
echo This is the first special file > ~/Special/firstfile
echo This is the second special file > ~/Special/secondfile

The specialcat function is used like:

> specialcat firstfile
This is the first special file

I want to enable argument completion so that

> specialcat firstf[TAB]


> specialcat firstfile

regardless of what the current working directory is and what files happen to be there.

This is my attempt so far

_options_specialcat () {
    COMPREPLY=( $(compgen -W "$(ls ~/Special)") )

complete -F _options_specialcat specialcat

which leads to

> specialcat firstf[TAB]
firstfile   secondfile  
> specialcat firstf

That is, pressing tab on a partial file name will display the list of files, but will not complete the command.

How do I alter my _options_specialcat function to produce the desired behavior?

  • COMPREPLY=( $(compgen -W "$(ls ~/Special)" -- "$1") ) Jul 1, 2016 at 4:35
  • Now nothing happens when I TAB. I'm on OSX if that makes a difference.
    – panofsteel
    Jul 1, 2016 at 11:36
  • I changed it to COMPREPLY=( $(compgen -W "$(ls ~/Special)" -- "$2") ) and it worked! If you post as an answer I will gladly accept it.
    – panofsteel
    Jul 1, 2016 at 12:27

1 Answer 1


You need to filter the list by the current argument, so:

COMPREPLY=( $(compgen -W "$(ls ~/Special)" -- "$2") )
  • 1
    For future readers, you can also access the current word with ${COMP_WORDS[COMP_CWORD]} rather than hard-coding the parameter number.
    – panofsteel
    Jul 2, 2016 at 2:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.