3

I have a project-specific setup file that I source right before running gnu screen.

In that file, I set up bash completion for my test command and the related tests.

That looks like this:

$PROJECT_HOME/app/bin/lib/behat_suites.sh  # _behat_suites() defined here
complete -F _behat_suites run_behat_suite
export -f _behat_suites

Problem is, each screen is a new shell, and the complete -F setting doesn't survive (rest of then environment does - they're proper subshells).

The export means the function survives into the screen sub-shells, but the completion setting itself doesn't.

Short of a tool like direnv, or putting the setting in my user ~/.bashrc, is there a way to get the completion setting to be inherited by the child shell processes?

1

I don't see any method for doing this, easily. You'd have to pass the output of complete -p from the parent shell to the child shells.

To start this allows for you to inject extra commands to the subshell:

$ bash --rcfile <(echo '. ~/.bash_profile')

Now if we try and introduce complete -p to this, like so:

$ bash --rcfile <(echo '. ~/.bash_profile'; while read line; do echo "$line"; done < <(complete -p))
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]

It almost works, it appears to be getting tripped up on the complete commands coming in. Trying to use a file as the intermediate didn't work either:

$ complete -p > /tmp/cmp.txt; bash --rcfile <(echo '. ~/.bash_profile'; echo '. /tmp/cmp.txt')
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]

Trying to see why it's failing doesn't really shed much additional light on things. Here I'm enabling verbose output from bash via the -set -x:

$ bash
$ set -x

We then source the file we made a second ago:

$ . /tmp/cmp.txt
+ . /tmp/cmp.txt
++ complete -F _manila manila
++ complete -F _minimal
complete: usage: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
++ complete -F _command time
++ complete -F _command do
++ complete -o bashdefault -o default -o nospace -F __git_wrap_git_checkout gcob

So unless there's some cleverness, it looks like the data contained within the output of complete -p is not portable in this particular case.

References

1

You don't have to put all of the settings in your ~/.bashrc, but you could add a "one-liner" that sees if the _behat_suites function has been defined and the completion function has not been defined; if so, then define the completion.

Here's the one-liner, broken up a bit for readability:

declare -f _behat_suites          >/dev/null && 
  ! complete -p run_behat_suite   >/dev/null && 
      complete -F _behat_suites run_behat_suite

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.