OS: macOS
As I understand from reading on SO and some issues here, pipenv
launches non-login shells, which means it should ignore .bash_profile
, and only use .bashrc
:
"Because Pipenv only reads bashrc and that鈥檚 it. Use the above workarounds." - @uranusjr in #844
My .bashrc
is empty.
I've been moving around stuff in my dotfiles just to get pipenv
to work properly but I'm not having too much success. This is the error I see when pipenv shell
is run in a project directory:
bash: prompt_git: command not found
prompt_git
is a function defined in .bash_prompt
, which is sourced in .bash_profile
. So why is pipenv
still complaining?
In .bash_profile
, which pipenv
seems to be using, I've also tried doing conditionally sourcing this .bash_prompt
just to satisfy pipenv
:
if shopt -q login_shell; then
if [[ $- == *i* ]]; then
if [ -f ~/.bash_prompt ]; then
source ~/.bash_prompt
fi
fi
fi
But that isn't helping either.
I assume you use prompt_git
in your prompt? The $PROMPT_COMMAND
environment variable is executed for every prompt display, so the error is raised exactly because you don鈥檛 have the command defined.
So does pipenv read .bash_profile, after all?
Where and how should I define this env var so pipenv works?
No, the $PROMPT_COMMAND
environment variable was inherited from the parent shell. The general recommendation is to make .bash_prompt
available in both .bashrc
and .bash_profile
.
The general recommendation is to make .bash_prompt available in both .bashrc and .bash_profile.
Ok, this worked, thank you.
But I'm still a little confused, let me see if I understand: pipenv
's subshell inherited the $PROMPT_COMMAND
env var from its interactive login parent shell, and that variable had a reference for something that was only in .bash_profile
, but since pipenv
itself doesn't source that file, then basically $PROMPT_COMMAND
was referencing an undefined command?
Yeah I know, it鈥檚 very confusing, that鈥檚 how Bash works. A child process inherits the parent鈥檚 environment (unless explicitly set otherwise), so all environment variables are automatically available in a sub-shell without configuration. Bash functions, however, are not part of the environment, and are therefore not inherited.
Bash internally (as I understand it) stores $PROMPT_COMMAND
as a string, and eval
it for every prompt. It does not carry the referenced function with it when copied into the child shell (only the name, as a string), so the child shell gets a reference error when trying to eval
it.
I read here that it is also possible to use export -f
to make functions available in a child shell. I am not sure whether that works with pipenv shell
, however.
Awesome, thanks for the explanation.
Most helpful comment
No, the
$PROMPT_COMMAND
environment variable was inherited from the parent shell. The general recommendation is to make.bash_prompt
available in both.bashrc
and.bash_profile
.