Issues installing pipenv as terminal can't open .bash_profile for writing

I am in the Data Science career path and currently in the Python unit on the Learn Python: Pipenv exercise.

In the video, I’m instructed on how to install pipenv and then add it to the PATH with the vi command. The installation of pipenv goes fine, but when I follow the instructions to add pipenv to the path, I get the error “˜/.bash_profile” E212: Can’t open file for writing".

I looked up this error and I see that it is triggered if one does not have permission to write in the directory or the file name is not valid. I checked and .bash_profile exists as a hidden file under Users/hannah/.local/bin, and I can open that file and edit it manually. For that reason, I’m not sure why I cannot update the file as the video instructs.

I also checked with my boss (as I’m doing this course on my work computer), and he thinks there aren’t limits on permission to edit the file. He asked me to run sudo chown hannah:staff .bash_profile .config .tcshrc .zshrc .xonshrc to try and fix the issue, but I still can’t seem to update the file.

Any tips on how to overcome this issue? I’m new to both Python and the command line and not sure if I’ve left out anything important, so if I need to provide any more information, I’ll gladly do so. Thanks! :slight_smile:

What instruction is it that’s causing an issue? If you can directly open, edit and save that file then that’s probably easiest anyway, any text editor can do the job, just make sure it saves as plaintext (no rich text or otherwise).

Based on the staff group I’m guessing you’re on OSX? There’s a pretty good chance your default shell in now zsh instead of bash, try echo $SHELL from the terminal if you want a quick test.

If you are using zsh then you’d want to modify the relevant zsh files instead of bash anyway because there’s no guarantee zsh would ever look at the .bash_profile file (I’d assume that’d be .zshrc). The following discussion might have one or two useful elements (zsh vs bash on osx and bash_profile problems) and it also links to a stack exchange page describing the zsh profile set-up as in the purpose of each file:

There’s two possible related issues for the read/write. One is that you don’t own the file (perhaps it was written by root or similar) and seeing as its in your home folder you probably do want to have ownership. The second is that permissions flags limit read/write and execute options on any particular file, even if you owned the file if the permission flag for writing was turned off for the owner then you would not be able to write.

The following has a nice introduction to the various permissions and what they mean (or have a web search)-

It also describes the chmod command which can be used to modify the various read/write flags for a file (if that’s the problem).

Regarding the permissions issue running ls -l and viewing the permissions/ownership of .bash_profile might be wise or just stat .bash_profile. If you’re uncomfortable with the terminal a right-click and get info on the pop-up menu should give you details about the file (I think permissions are at the very bottom of that pop-up window, you might be able to modify them directly in the GUI).

2 Likes

Hi tgrtim!

Thanks for your answer. I’ll be honest, I’m still not sure how to fix my specific problem even after reading your resources. I’m trying to understand, but I am a total beginner. I’ll answer your questions first.

  • I am on OSX.

  • When i try echo $SHELL in the terminal, the result is /bin/zsh, so zsh does appear to be the default shell.

  • The instruction that is causing the issue is trying to edit the .bash_profile file using the command line. I’ve been instructed to do that with the following commands:

  1. pip install --user pipenv
  2. vi ~/.bash_profile (a text editor opens)
  3. add 'export PATH="Users/hannah/.local/bin:$PATH"
  4. type i and then type :wq!

Step 4 is where the problem E212: Can’t open file for writing error occurs.

I am able to edit the .bash_profile file manually, however. I also realized I can edit the .zshrc doc in the command line with above steps I outlined for trying to edit .bash_profile, without receiving an error.

  • Regarding permissions for .bash_profile (which it sounds like may be unnecessary anyway if the file I actually need to edit is .zrshc), when I run stat .bash_profile, the result is:
16777225 51463352 -rw-rw-r-- 1 hannah staff 0 451 "Jan 20 08:55:34 2022" "Jan 19 08:26:28 2022" "Jan 20 08:55:29 2022" "Sep  4 10:20:24 2021" 4096 8 0x40 .bash_profile

I’ve manually opened the .bash_profile info and changed the permissions for me and staff to Read & Write.

Screenshot 2022-01-20 at 08.55.45

I have a second problem:

Even if I edit .bash_profile or .zrshc manually, Codecademy didn’t properly specify what to do there is already other information in that file.

Both files have the same information below written in them:

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/opt/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/opt/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="/opt/miniconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<


The Codecademy video says that, if there is an export PATH="something/here:$PATH" line in the file already, that we should take the path that we were instructed to add to the file and put it in front of the other path information in quotes while keeping the colon, I assumed like so:

export PATH="Users/hannah/.local/bin:/opt/miniconda3/bin:$PATH" (this may seem dumb, but it was verbally explained like this and the video didn’t provide an example of how to handle this situation :sweat_smile:)

This does not work. Nor does adding the line export PATH="Users/hannah/.local/bin:$PATH" before or after the code related to the conda initialization.

I have tried looking at Stack Overflow and playing around with this on my own for a day or two now, but I’m really at a loss. Do you have any ideas?

Yes definitely zsh so you can mostly forget about .bash_profile.

If you really want to change `.bash_profile`

I’d highly recommend a text editor other than vi. Whilst vi is installed on basically every system in existence (or the slightly more modern vim) and it’s a very powerful text editor they’re not beginner friendly at all. Just use a different text editor, make sure you only ever save as plaintext though, no rich text or otherwise. The current permissions look like you should easily be able to edit it so I can only assume it’s trying to save in the wrong place

If you have the time I’d highly suggest learning some of the basics of the command line, either on cc or elsewhere as it will make this a lot clearer and demystify so many things about working with your computer. Since it’s the standard user interface to interact with the OS you’ll likely be making more and more use of it as you learn more programming (I certainly think it’s worthwhile, but it’s up to you).

The whole introduction pipenv is a bit of a mess really, whilst it is nice pipenv is not an essential tool; if you’ve already got conda you could just use that to manage environments or python’s standard module package management tools are more than adequate for most users. In short, you could drop this whole section without any negative effects in my opinion.

I hadn’t seen you were working with pipenv the first time around. One quick thing to test is does python -m pipenv or perhaps more likely on OSX python3 -m pipenv let you run pipenv? If so you can skip digging around in your PATH and just use it that way. With an alias you could even link that text to a shorter option, e.g.

alias penv="python3 -m pipenv"
# or stick with the classic-
alias pipenv="python3 -m pipenv"

An alias can be added to your .zshrc to set it every time you start your shell.


Regarding the bit about conda in the .zshrc file. That particular section is designed to set up conda in your shell as you’ve already surmised.

You’d want to your new addition entirely outside that section (before # >>> conda initialize >>> or after # <<< conda initialize <<<. If you’ve already tried this and restarted the terminal but still cannot run pipenv I can only assume that there is no link to pipenv from /Users/hannah/.local/ so going back to python3 -m pipenv might be the easiest option (there are other options but they all do the same thing at the end of the day).

That PATH should start with /Users though, not Users, the first / is the root directory which you must include.

2 Likes

In addition to all the excellent information that @tgrtim has provided (trust me, we’ve answered many questions about pipenv here :slight_smile:) I found this video has helped people understand a bit more about virtual environments & why you’d need them. This portion of the DS course throws everyone b/c it deals with the command line and that’s something that’s a mystery to many.

Also, since you’re doing this at work…I wondered: are you even going to be writing scripts in different environments (with different versions of Python) using the CL or are you going to be using an IDE with a GUI (like PyCharm, Visual Studio, etc), updating code in a version control system? I suspect an IDE. Don’t get me wrong, understanding virtual environments and installing packages is an important thing to learn…but, if you’re not going to use it, it becomes sort of “dusty” knowledge. Unless you’re also going to do this on your own computer…I’d highly recommend using Homebrew to install things on a Mac. Off topic, sort of…I’d also recommend looking into Google Colab in addition to learning Jupyter Notebook (it’s essentially the same in many ways except it’s cloud-based in one’s GDrive).

And, again all of this pretty much looks like this on many peoples’ machines (myself included lol):

2 Likes

Hi again @tgrtim .

Thank you for yet another detailed response! I am so grateful. I learned some of the basics of the command line from Codecademy, but I agree now having done this “exercise” that I should deepen my understanding by finishing that course. I’m also just going to avoid .bash_profile, as it sounds like it’s not necessary to use right now.

Thank you for clarifying that pipenv is not 100% necessary since Python and Conda already have options that work for most environment management situations. I’ll check out those links.

Sorry for not specifying that I was working with pipenv. :sweat_smile: When I enter python3 -m pipenv, it returns a large body of text that I’ll include at the end of this message. I assume this means that I am running pipenv. :slight_smile: Cool tip about the alias as well! If I end up needing to use pipenv, I will add the alias to my .zshrc file to save time.

Thank you for specifying about where to actually put the additional PATH in the .zshrc file. I believe I tried adding it in the correct place at one point but was missing the forward slash. I just tried it again by opening the .zrsch file in the GUI and adding the export PATH="/Users/hannah/.local/bin:$PATH" below the Conda information. Now, when I open a new terminal and enter pipenv, the same message from running python3 -m pipenv, appears, which I think means it’s working now :smiley:

Thank you for your patience. I have learned so much just from struggling with this issue and reading your responses. :pray:


Usage: python -m pipenv [OPTIONS] COMMAND [ARGS]...

Options:
  --where                         Output project home information.
  --venv                          Output virtualenv information.
  --py                            Output Python interpreter information.
  --envs                          Output Environment Variable options.
  --rm                            Remove the virtualenv.
  --bare                          Minimal output.
  --man                           Display manpage.
  --support                       Output diagnostic information for use in
                                  GitHub issues.
  --site-packages / --no-site-packages
                                  Enable site-packages for the virtualenv.
                                  [env var: PIPENV_SITE_PACKAGES]
  --python TEXT                   Specify which version of Python virtualenv
                                  should use.
  --three / --two                 Use Python 3/2 when creating virtualenv.
  --clear                         Clears caches (pipenv, pip).  [env var:
                                  PIPENV_CLEAR]
  -v, --verbose                   Verbose mode.
  --pypi-mirror TEXT              Specify a PyPI mirror.
  --version                       Show the version and exit.
  -h, --help                      Show this message and exit.


Usage Examples:
   Create a new project using Python 3.7, specifically:
   $ pipenv --python 3.7

   Remove project virtualenv (inferred from current directory):
   $ pipenv --rm

   Install all dependencies for a project (including dev):
   $ pipenv install --dev

   Create a lockfile containing pre-releases:
   $ pipenv lock --pre

   Show a graph of your installed dependencies:
   $ pipenv graph

   Check your installed dependencies for security vulnerabilities:
   $ pipenv check

   Install a local setup.py into your virtual environment/Pipfile:
   $ pipenv install -e .

   Use a lower-level pip command:
   $ pipenv run pip freeze

Commands:
  check      Checks for PyUp Safety security vulnerabilities and against PEP
             508 markers provided in Pipfile.
  clean      Uninstalls all packages not specified in Pipfile.lock.
  graph      Displays currently-installed dependency graph information.
  install    Installs provided packages and adds them to Pipfile, or (if no
             packages are given), installs all packages from Pipfile.
  lock       Generates Pipfile.lock.
  open       View a given module in your editor.
  run        Spawns a command installed into the virtualenv.
  scripts    Lists scripts in current environment config.
  shell      Spawns a shell within the virtualenv.
  sync       Installs all packages specified in Pipfile.lock.
  uninstall  Uninstalls a provided package and removes it from Pipfile.
  update     Runs lock, then sync.
(base) hannah@MacBook-Pro ~ %
2 Likes

Hi @lisalisaj,

Thank you for your message! I will watch that video, and I’m glad to know I wasn’t the only one lost on this section. :relieved:

When I say I’m doing this at work, I mean I am using my work computer, but I am not using this for my actual work. I’m doing the course for personal learning. It’s likely this will become “dusty” knowledge that is good to have encountered, but that I (at least for some time) won’t be using on a daily basis.

I appreciate the recommendations for Homebrew and Google Colab, as I had seen Homebrew pop up while searching for solutions to this problem, and I’ve been using Jupyter Notebook during the course. Alternatives are always nice to explore :smiley:

I also love the funny graphic. Definitely captures my utter confusion I felt whilst tackling this issue.

2 Likes