Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update shell configuration info in README #1359

Closed
wants to merge 2 commits into from

Conversation

AmaiKinono
Copy link

  • ~/.bash_profile may not be sourced in desktop environment. When this happenes, ~/.profile can be used instead.
  • The pyenv function should be exported if eval $(pyenv init -) is put into ~/.profile or ~/.bash_profile.

- `~/.bash_profile` may not be sourced in desktop environment. When this happenes, `~/.profile` can be used instead.
- The `pyenv` function should be exported if `eval $(pyenv init -)` is put into `~/.profile` or `~/.bash_profile`.
@georgalis
Copy link

Thanks! I would be more specific about when to use export -f pyenv because readers of the doc won't know whether "may need" applies to them or when it might apply to them in the future. Explaining when export must be used, will remove confusion.

@AmaiKinono
Copy link
Author

My thought is when put eval $(pyenv init -) in ~/.profile or ~/.bash_profile, export -f pyenv is needed. But I didn't say that because I am not sure if this is true for most environments, so I simply say "if pyenv shell or pyenv rehash doesn't work, you should do this." I'd like to hear your thought about this.

@georgalis
Copy link

My thought is shell configuration schemes are a mess and that has a lot to do with why users so often have broken environments or are confused about their setup. While the invocation section of shell man pages seem carefully written enough, there is no explanation of the requirements driving the complexity.

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well. When invoked as an interactive login shell, or a non-interactive shell with the --login option, it first attempts to read and execute commands from /etc/profile and ~/.profile, in that order. The --noprofile option may be used to inhibit this behavior. When invoked as an interactive shell with the name sh, bash looks for the variable ENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as sh does not attempt to read and execute commands from any other startup files, the --rcfile option has no effect. A non-interactive shell invoked with the name sh does not attempt to read any other startup files. When invoked as sh, bash enters posix mode after the startup files are read.

The only case for different shell configurations I know of is interactive or non-interactive; so, I source .profile from .bashrc, then in .profile I use a conditional return if non-interactive, test -t 0 || return 0 before setting interactive variables, aliases and functions. This way I have one file for all my shell configurations, and I can use it on all the different systems I use.

I use additional branches within that file to detect OS, installed software and the specific shell, so aliases, functions and environmental configurations only get set when appropriate.

I source ~/.profile from all of my shell rc files (zsh, ksh, bash, etc) to keep all of my configuration in one file. That file checks if it is sourced from a non-interactive shell and returns without error if so, which keeps scp (and anything else using the shell programmatically) from breaking.

The thing to keep in mind is shell environment setup is not by design, it's by evolution. There probably isn't a good answer for everyone today. I like the idea of exporting functions from profile, it works when you use run control (rc) files for run control and profile for interactive function setup, as best I can tell. For me, I'll source my .profile from run control (rc files) and do my best to test the environment before setting anything that isn't universal (eg, only set zsh features in zsh, etc).

As for what is best in pyenv docs, not sure, but I would avoid anything like 'you may need' in documentation or instructions about what you actually need. Better to state the circumstances you can think of, eg

  • Put eval $(pyenv init -) where you define interactive functions, such as .profile or .bash_profile
  • You will need to export -f pyenv to access the function from a sub-shell, such as a desktop environment.

Nobody wants to be definitive about how anybody in the world should always setup their system, and there is usually more than one solution. But if you explain how to deal with the specific problem cases you can think of, that's good documentation and the elucidation sometimes identifies a better coding solution too.

BTW - my favorite shell is ksh but the good version is only available on NetBSD, so I usually use bash on Mac and Linux.

@AmaiKinono
Copy link
Author

It's updated.And thank @georgalis for sharing your setup! It makes a lot of sense,, and maybe I should do it in the same way.

@blueyed
Copy link
Contributor

blueyed commented Sep 23, 2019

Would be great to get this via rbenv's (upstream) README: https://github.com/rbenv/rbenv/blob/master/README.md

There are changes in this regard IIRC, so it would be good to not derive further from it, but get it straight via/from there.


If you put this in the run control file (like `~/.bashrc`), this will work fine; otherwise (like if you
use `~/.bash_profile` or `~/.profile` instead, and it is not sourced in `~/.bashrc`), you need to put
`export -f pyenv` after this to access the function from a sub-shell.
Copy link

@nchammas nchammas Feb 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should/could export -f pyenv instead somehow be part of pyenv init -? That would avoid adding any extra steps for users to do.

Perhaps somewhere inside this block:

pyenv/libexec/pyenv-init

Lines 138 to 154 in 7097f82

if [ "$shell" != "fish" ]; then
IFS="|"
cat <<EOS
command="\${1:-}"
if [ "\$#" -gt 0 ]; then
shift
fi
case "\$command" in
${commands[*]})
eval "\$(pyenv "sh-\$command" "\$@")";;
*)
command pyenv "\$command" "\$@";;
esac
}
EOS
fi

(FWIW, I found this PR via #1347. I was having the same issue with sub-shells and your suggestion there fixed things for me. Thanks!)

@native-api
Copy link
Member

Superseded by #1920

@native-api native-api closed this May 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants