Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

If in bash, I do "set -P" then bash follows the "physical directory structure" when doing "pwd" and "cd .." etc, rather than the "logical one" that might be defined via symlinks. Unfortunately, bash still doesn't obey the physical directory structure for filename completion. How can I get bash to respect my authority on this issue?


P.S. Unfortunately, the same problem has now afflicted Emacs for opening files, etc. If anyone also knows how to also tell Emacs to respect my physical directory structure, then I'd also like to know the answer to that.

P.P.S. I don't know who decided that having some programs try to fathom your "logical directory structure" was a good idea, but it's not! Not unless you can convince every program in the world to do things this way, since having some programs use your physical directory structure, and having other ones use your logical directory structure is a recipe for confusion and annoyance.

share|improve this question
I don't understand the problem. Are you not able to open files? Is bash completion getting the wrong path? – James Polley Jan 5 '10 at 23:21
That depends on what you mean by "wrong". Bash is not following the Unix meaning of "..", which is a real directory entry in a directory, and points to the physical parent directory. Instead bash is interpreting ".." to mean "strip one entry off the path that I took to get here". I don't want to use this fancy newfangled meaning. I want the normal Unix meaning. – Douglas Jan 6 '10 at 19:42

Thanks for the previous answers. But, actually, as it turns out, "set -P" does the job just fine all by itself, contra my original query on the issue.

When I was originally trying this out, I must have somehow gotten bash into a confused state where filename completion wasn't respecting the "set -P" setting. But now with a fresh bash, it's all working fine. "set -P" seems to put bash into "physical directory structure" mode consistently throughout bash.

share|improve this answer

This might get you part of the way there.

Use type -a _expand and compare its output to the function below. The existing function should match the part that's after the first else below. If not, you can wrap what you have in the outer if...else as you see it here.

Paste it at a Bash prompt to test. Then, if you're satisfied, put it in your ~/.bashrc file to override the function definition in /etc/bash_completion (instead of editing it directly).

_expand ()
    if [[ $- == *P* && -L "$cur" && -d "$cur" ]]; then
        cd "$cur";
        eval cur="$PWD";
        cd - > /dev/null;
        if [[ "$cur" == \~*/* ]]; then
            eval cur=$cur;
            if [[ "$cur" == \~* ]]; then
                COMPREPLY=($( compgen -P '~' -u $cur ));
                [ ${#COMPREPLY[@]} -eq 1 ] && eval COMPREPLY[0]=${COMPREPLY[0]};
                return ${#COMPREPLY[@]};

This is piggy-backing on the tilde-expansion function of Bash's tab completion.

Now you can do

ls -l symdir<TAB>

and you'll see

ls -l /dest/dir<CURSOR>
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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