[Bash-completion-devel] Bug#857235: Bug#857235: bash-completion: /etc/profile.d/bash_completion.sh can't be forcibly re-run

Stephen Dowdy sdowdy at ucar.edu
Thu Mar 9 22:50:40 UTC 2017


On 03/09/2017 02:48 AM, Ville Skyttä wrote:
> I don't know what the reason for making the variable read only is. But
> I think you could work around it by setting BASH_COMPLETION_COMPAT_DIR
> to a fake value, e.g. /prevent/sourcing in your rc files before the
> profile.d snippet is sourced (thus preventing it from loading
> bash_completion), and then unsetting it before "manually" loading the
> profile.d snippet where you want, and let it do its job unmodified.

Ville,

Problem here is that bash invokes /etc/profile prior to the end-user having control via .bashrc.  All that stuff in /etc/profile.d/bash_completion.sh is performed outside my control. (i prefer not to mangle up too many system-provided files, or affect my user's expectations of the environment)

It might be possible to set it via 'pam_env' or something (which *should* take effect prior to the shell invoking /etc/profile) That's a little messy, and i'd prefer not to have to bring yet another component into the picture.

But, let's do a proof-of-concept:

    # cat ~/.pam_environment
    BASH_COMPLETION_COMPAT_DIR="BOGUS"
    
    # cat /root/.bashrc
    .....
    \unset -f unalias ; \unalias -a ; \unset -f command
    \unset LD_LIBRARY_PATH LD_PRELOAD SHELLOPTS CDPATH HISTFILE HOSTFILE INPUTRC 2>/dev/null
    confpath="$(command -p getconf PATH 2>/dev/null)"
    # Establish baseline path with no NFS components
    export PATH="/opt/sbin:/opt/bin:/sbin:/usr/sbin:${confpath:-/bin:/usr/bin}"
    \type typeset >/dev/null && \unset -f $(\typeset -f | \grep '()' | \cut -d' ' -f1)
    .....
    is_shell_interactive() { [ "${-%i*}" != "${-}" ] ;}
    .....
    if is_shell_interactive; then
        # RELOAD bash-completion
    echo "DEBUG: BASH_COMPLETION_COMPAT_DIR[before]=${BASH_COMPLETION_COMPAT_DIR}" 1>&2
    unset BASH_COMPLETION_COMPAT_DIR
    . /etc/profile.d/bash_completion.sh
    echo "DEBUG: BASH_COMPLETION_COMPAT_DIR[after]=${BASH_COMPLETION_COMPAT_DIR}" 1>&2

Results in, when i remote 'ssh' login:

    DEBUG: BASH_COMPLETION_COMPAT_DIR[before]="BOGUS"
    DEBUG: BASH_COMPLETION_COMPAT_DIR[after]=/etc/bash_completion.d

    # set | grep longopt\ \(
    _longopt ()
    _split_longopt ()

So, indeed, that *will* work -- presuming pam_env PAM enabled services (my ssh+su+login config at least uses it).

Thanks for the idea.  That gets me a drop on doing this now (other than what i was doing, which was just invoking the two command lines that /etc/profile.d/bash_completion.sh script was doing inside the conditional block).   I think it still would be conceptually better to not have to rely on pam_env for this to work, and have bash-completion implement some re-sourcable invocation mechanism.

--stephen



More information about the Bash-completion-devel mailing list