Problem with changing python statement with python3 in macOS Catalina - python

By default when I type python in terminal it goes to python using the 2.7.x version. In oldest versions of macOS once I typed 'alias pyhton=python3' it changed forever and every time I typed python it goes to python version 3.
But in macOS Catalina, I need to type the statement every time I open the terminal.
Any suggestion?

First up, confirm what your default "python" links to, so you can reference it, and ensure that which and the shell agree:
user:~> which python
/usr/bin/python
user:~> type python
python is /usr/bin/python
user:~> ls -la /usr/bin/python
lrwxrwxrwx 1 root root 7 Oct 8 13:26 /usr/bin/python -> python2
Now you can either add an alias to override this in your shell... .
Open your ~/.bash_profile file for bash or ~/.zshrc file for zsh (look here for historical reasons behind the files used) as suggested by shahaf, and add a line with the alias — for example, quick method:
echo "alias python=/usr/bin/python3" >> ~/.bash_profile
echo "alias python=/usr/bin/python3" >> ~/.zshrc
The new alias will be set for the next shell you start, or, open a new Terminal window and source the profile file to make it active. Eg. in bash:
source ~/.bash_profile
Or, change the symlink to point by default to python3, and remember the change (I use a simple toggle script, else any install of a missing python2 package can result in complaints about the configure script, which uses the python symlink directly):
#!/bin/bash
TOGGLE=$HOME/.python3Active
if [ ! -e $TOGGLE ]; then
touch $TOGGLE
sudo ln -fs python3 /usr/bin/python
ls -la /usr/bin/python
echo "Press any key to continue..."
read
else
rm $TOGGLE
sudo ln -fs python2 /usr/bin/python
ls -la /usr/bin/python
echo "Press any key to continue..."
read
fi

Catalina now uses zsh as the default rather than Bash.
To verify which shell you are using type echo $0 in the terminal
Add alias python='python3' to $HOME/.zshrc

you will have to edit the terminal's profile file, usually reside under ~/.profile
add the alias line there, this files get loaded when a terminal session is started and export environment variables and methods so they will be accessible in that session
I suggest to use a more robust and powerful terminal enhancement like Z-Shell

Related

python path directing to older version in PATH

In Linux when I issue the following command:
echo $PATH
/opt/python/3.10.8/bin/python3:/home/d5291029/.local/bin:/home/d5291029/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/puppetlabs/bin
I get this. My .bash_profile is this:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
PATH=/opt/python/3.10.8/bin/python3:$PATH
When I source the changes in bash_profile source .bashprofile and hit:
python3
Python 3.6.8 (default, Jun 14 2022, 12:54:58)
So even though my python is version 3.10 , my path still defaults to the system installation version of python which is 3.6.8. Why is that ?
PATH should contain directory paths, not program.
You can fix this:
PATH=/opt/python/3.10.8/bin:$PATH
Don't forget to logout or exec bash to reload your .bash_profile.

ZSH - pyenv 'command not found' on login or new window - works on load.

I'm using ZSH/oh-my-zsh and the regular OSX terminal, though the same problem occurs in iTerm. I'd been using rbenv and nvm without issue, but recently started working with python and pyenv, and have run into the following issue. On loading a new terminal window, I get the following message at the prompt:
Last login: Sat Apr 1 11:56:46 on ttys001
/Users/jackfuller/.zshenv:3: command not found: pyenv
Since installing pyenv, my machine seems noticeably slower. Obviously loading pyenv will slow things down but load times have dropped way off.
The catch is that pyenv works perfectly after the terminal is loaded, and as far as I can tell my .zshrc is configured properly:
alias dev="cd ~/development"
alias gow="cd ~/goworkspace"
alias dl="cd ~/downloads"
export PATH=/usr/local/bin:$HOME/bin:$PATH
export EDITOR='atom -n'
export PAGER='less -f'
export PATH=$HOME/.rbenv/shims:$PATH
RBENV
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi
# NVM
export NVM_DIR="/Users/jackfuller/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
# PYENV
export PYENV_ROOT=/usr/local/opt/pyenv
eval "$(pyenv init - --no-rehash)"
# if which pyenv > /dev/null; then eval "$(pyenv init - --no-rehash)";
fi
# For go.
export GOPATH="$HOME/goworkspace"
export PATH=$PATH:/usr/local/go/bin
export GOROOT="usr/local/go"
If anyone can offer any advice/solutions, it would be much appreciated. Environment variables and shell config files seem more temperamental /confusing than they should be.
/Users/jackfuller/.zshenv:3: command not found: pyenv indicates that your error is in .zshenv at line 3. Maybe you could post your .zshenv. Is there a reason the fi after #PYENV is not commented? Also you could do export PATH=... once and not thrice. Try which pyenv to find the path to pyenv and look if its in your $PATH. For Future uses i'd put my aliases into ~/.zsh_aliases and do a source ~/.zsh_aliases in the .zshrc, otherwise it gets pretty ugly once you have some more aliases. Sorry for the bad structured answer ;)

virtualenv without interfering #!/usr/bin/env python

My application is writen in python 3, and I work in a virtualenv. On my cluster, there is hdp (hortonworks) installed and some scripts require python 2. Those script have #!/usr/bin/env python in the header, but it links to my python 3 installation because my virtualenv is activated. How to solve this ? I can't modify hdp source for obvious reasons.
Modifying Your Virtualenv
If you want your virtualenv to always be ignored with a #!/usr/bin/env python shebang (but not with a #!/usr/bin/env python3 shebang), there's a big-hammer approach that prevents the python entry in the PATH added by the virtualenv from matching, but doesn't necessarily perform other cleanup:
rm "$VIRTUAL_ENV/bin/python"
...or a better-behaved alternative (assuming that you have a python2.7 in your PATH, and that it's what you want to use):
cat >"$VIRTUAL_ENV/bin/python" <<'EOF'
#!/usr/bin/env bash
path_prefix=$VIRTUAL_ENV/bin:
if [[ $PATH = $path_prefix* ]]; then
PATH=${PATH#$path_prefix}
fi
unset PYTHONHOME VIRTUAL_ENV
exec python2.7 "$#"
EOF
The below will assume you're looking for approaches with a bit more finesse.
Command-Specific Shell Wrapper
If you interact with Hortonworks through a frontend called hdp, consider the following a shell function, a wrapper for hdp that deactivates the virtualenv:
hdp() (
if [[ $VIRTUAL_ENV ]]; then
deactivate
fi
exec command hdp "$#"
)
Because this function is using parentheses instead of curly braces, it runs in a subshell -- a separate copy of the shell environment -- so when it runs deactivate, this doesn't impact your parent shell. This also means that the exec command causes the subshell to replace itself with the hdp command, rather than causing your parent shell to terminate.
Generic Shell Wrapper
If you want to be able to run other scripts with your virtualenv temporarily deactivated, consider instead:
# wv == "without virtualenv"
wv() (
if [[ $VIRTUAL_ENV ]]; then
deactivate
fi
exec "$#"
)
...such that wv foo will run foo with the virtualenv deactivated.

Updating .bashrc and environment variables during Vagrant provisioning

I'm using Vagrant to set up a box with python, pip, virtualenv, virtualenvwrapper and some requirements. A provisioning shell script adds the required lines for virtualenvwrapper to .bashrc. It does a very basic check that they're not already there, so that it doesn't duplicate them with every provision:
if ! grep -Fq "WORKON_HOME" /home/vagrant/.bashrc; then
echo 'export WORKON_HOME=/home/vagrant/.virtualenvs' >> /home/vagrant/.bashrc
echo 'export PROJECT_HOME=/home/vagrant/Devel' >> /home/vagrant/.bashrc
echo 'source /usr/local/bin/virtualenvwrapper.sh' >> /home/vagrant/.bashrc
source /home/vagrant/.bashrc
fi
That seems to work fine; after provisioning is finished, the lines are in .bashrc, and I can ssh to the box and use virtualenvwrapper.
However, virtualenvwrapper doesn't work during provisioning. After the section above, this next checks for a pip requirements file and tries to install with virtualenvwrapper:
if [[ -f /vagrant/requirements.txt ]]; then
mkvirtualenv 'myvirtualenv' -r /vagrant/requirements.txt
fi
But that generates:
==> default: /tmp/vagrant-shell: line 50: mkvirtualenv: command not found
If I try and echo $WORKON_HOME from that shell script, nothing appears.
What am I missing to have those environment variables available, so virtualenvwrapper will run?
UPDATE: Further attempts... it seems that doing source /home/vagrant/.bashrc has no effect in my shell script - I can put echo "hello" in the .bashrc file , and that isn't output during provisioning (but is if I run source /home/vagrant/.bashrc when logged in.
I've also tried su -c "source /home/vagrant/.bashrc" vagrant in the shell script but that is no different.
UPDATE 2: Removed the $BASHRC_PATH variable, which was confusing the issue.
UPDATE 3: In another question I got the answer as to why source /home/vagrant/.bashrc wasn't working: the first part of the .bashrc file prevented it from doing anything when run "not interactively" in that way.
The Vagrant script provisioner will run as root, so it's home dir (~) will be /root. In your script if you define BASHRC_PATH=/home/vagrant, then I believe your steps will work: appending to, then sourcing from /home/vagrant/.bashrc.
Update:
Scratching my earlier idea ^^ because BASHRC_PATH is already set correctly.
As an alternative we could use .profile or .bash_profile. Here's a simplified example which sets environment variable FOO, making it available during provisioning and after ssh login:
Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise32"
$prov_script = <<SCRIPT
if ! grep -q "export FOO" /home/vagrant/.profile; then
sudo echo "export FOO=bar" >> /home/vagrant/.profile
echo "before source, FOO=$FOO"
source /home/vagrant/.profile
echo "after source, FOO=$FOO"
fi
SCRIPT
config.vm.provision "shell", inline: $prov_script
end
Results
$ vagrant up
...
==> default: Running provisioner: shell...
default: Running: inline script
==> default: before source, FOO=
==> default: after source, FOO=bar
$ vagrant ssh -c 'echo $FOO'
bar
$ vagrant ssh -c 'tail -n 1 ~/.profile'
export FOO=bar
I found a solution, but I don't know if it's the best. It feels slightly wrong as it's repeating things, but...
I still append those lines to .bashrc, so that virtualenvwrapper will work if I ssh into the machine. But, because source /home/vagrant/.bashrc appears to have no effect during the running of the script, I have to explicitly repeat those three commands:
if ! grep -Fq "WORKON_HOME" $BASHRC_PATH; then
echo 'export WORKON_HOME=$HOME/.virtualenvs' >> $BASHRC_PATH
echo 'export PROJECT_HOME=$HOME/Devel' >> $BASHRC_PATH
echo 'source /usr/local/bin/virtualenvwrapper.sh' >> $BASHRC_PATH
fi
WORKON_HOME=/home/vagrant/.virtualenvs
PROJECT_HOME=/home/vagrant/Devel
source /usr/local/bin/virtualenvwrapper.sh
(As an aside, I also realised that during vagrant provisioning $HOME is /root, not the /home/vagrant I was assuming.)
The .bashrc in Ubuntu box does not work. You have to create the .bash_profile and add:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
As mentioned in your other Q, Vagrant prohibits interactive shells during provisioning - apparently, only for some boxes (need to reference this though). For me, this affects the official Ubuntu Trusty and Xenial boxes.
However, you can simulate an interactive bash shell using sudo -H -u USER_HERE bash -i -c 'YOUR COMMAND HERE'
Answer taken from: https://stackoverflow.com/a/30106828/4186199
This has worked for me installing Ruby via rbenv and Node via nvm when provisioning the Ubuntu/trusty64 and xenial64 boxes.

Cannot execute a python script without getting to the folder MacOSX

I am using MacOSX Yosemite, I am trying to execute a python code without always typing the path or getting into the folder. I tried the following :
1) Added the line #! /usr/local/bin/python (after finding where the python is found)
2) sudo chmod a+x full_file_path
But this does not work for me. Nor
export PYTHONPATH=full_file_path
How else can I execute the python script without actually getting into the directory. I cannot also execute the script without using ./ the chmod does not change the access to executable. Which as far as I have seen many forums. It should.
You need to add full_file_path to your shell PATH variable. It is your shell that does the searching for the script, not Python. Only when the script has been found, is Python being started:
export PATH="full_file_path:$PATH"
You can add that line to your .bash_profile or .profile file in your home directory to make this addition permanent.
Run these commands without the $ signs in the front:
$ ls -l /full/directory/progname.py
$ chmod +x /full/directory/progname.py
$ ls -l /usr/local/bin/python
$ export PATH="$PATH:/full/directory"
$ progname.py
If any of the ls commands display an error message, then you are looking for the file in the wrong place, and you have to find the correct location, and update the command accordingly.
It's important to note that /usr/local/bin/python can also be wrong, for example some systems have the Python interpreter in /usr/bin/python.

Categories