daveoncode
daveoncode

Reputation: 19578

Reloading environment variables inside a bash script

I'm writing a series of Ubuntu post-install scripts in order to install libraries and tools I need, one of this should install pyenv and latest python version using the former, the script is the following:

#!/usr/bin/env bash

# clone the github repo
echo "Installing pyenv..."
git clone https://github.com/yyuu/pyenv.git ~/.pyenv

# update .bashrc
echo '# pyenv settings:' >> ~/.bashrc
echo 'export PYENV_ROOT="~/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'export PATH="~/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

# reload
. ~/.bashrc

# install python and virtualenv
echo "Installing python 3.5.1 + virtualenv..."
pyenv install 3.5.1
pyenv global 3.5.1
pip install --upgrade pip
pip install virtualenv
echo "pyenv has been installed with python 3.5.1 and virtualenv"

The problem is that the reload (. ~/.bashrc) seems to not work as expected,because I get:

python.sh: pyenv: not found
python.sh: pip: not found

I also tried with source ~/.bashrc and exec $SHELL but the problem remains.

How can I solve the problem?

ps: I'm executing the script with: sudo sh python.sh

Upvotes: 0

Views: 1452

Answers (2)

totoro
totoro

Reputation: 2456

Dangerous to manipulate ~/.bashrc, you don't need to either, unless you want something to be permanent.

Change

echo 'export PYENV_ROOT="~/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'export PATH="~/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

to

export PYENV_ROOT="~/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export PATH="~/.pyenv/bin:$PATH"
eval "$(pyenv init -)"

and the rest of the script will use the modified variables, even subshells.

EDIT

To make it permanent write it to a ~/.pyenvrc and just modify ~/.bashrc by appending

source ~/.pyenvrc

Upvotes: 0

chepner
chepner

Reputation: 531055

If ~ is quoted, it does not expand to the user's home directory. Use this instead.

echo '# pyenv settings:' >> ~/.bashrc
echo 'export PYENV_ROOT=~/.pyenv' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'export PATH=~/.pyenv/bin:"$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

I would also rewrite it to look something like this:

cat <<'EOF' >> ~/.bashrc
# pyenv settings:
export PYENV_ROOT=~/.pyenv
export PATH=$PYENV_ROOT/bin:$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
EOF

However, you shouldn't be sourcing the user's .bashrc file; you don't know what else is in there, and you don't need to execute the whole thing, just the parts needed for the rest of your script. Replace . ~/.bashrc with

export PYENV_ROOT=~/.pyenv
export PATH=$PYENV_ROOT/bin:$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"

Upvotes: 1

Related Questions