可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'd like to use the SiblimeREPL package with Sublime Text. When I try to start a REPL, I get
SublimeREPL: obtaining sane environment failed in getenv()
Check console and 'getenv_command' setting
WARN: Falling back to SublimeText environment
This happens regardless of which REPL I try to start. (I tried Ruby, Python, and Clojure.) I tried Sublime Text 2 and Sublime Text 3 with the same results. This is on Mac OS X, if that matters.
I looked in the package settings, where I see
"getenv_command": ["/bin/bash", "--login", "-c", "env"],
If I run "/bin/bash --login -c env" at a Terminal prompt, I get my environment listed.
What do I need to change in order to get a successful getenv_command?
回答1:
I had the same problem as ssgam. The problem line for me is in the getenv method. It calls subprocess.check_output(getenv_command), which doesn't exist in python 2.6, which ST2 seems to use.
The trick is, it only calls subprocess.check_output() if getenv_command is truthy, and defaults to os.environ.copy() otherwise. So to get ssgam's fix without modifying the SublimeREPL package, in Preferences > Package Settings > SublimeREPL > Settings - User, do something like this:
{
"getenv_command": false
}
回答2:
I investigated this issue a little bit deeper and it seems SublimeText 3 is also affected. In my case the problem is related to bash-completion feature, in particular COMP_WORDBREAKS environment variable.
Use the following command to show the contents of COMP_WORDBREAKS:
$ echo "$COMP_WORDBREAKS"
will output
"'><=;|&(:
You can also use:
$ echo $COMP_WORDBREAKS
but note that with the second command (without quotes), you'll not see that
the variable also contains a line feed character.
The problem here is the line feed character which breaks output parsing in getenv_command feature. If you extract part of the source code for SublimeREPL you can get real error message from python interpreter.
Traceback (most recent call last):
File "main.py", line 71, in getenv
env = dict(line.split('=', 1) for line in lines)
ValueError: dictionary update sequence element #6 has length 1; 2 is required
You can match element #6 with the position of COMP_WORDBREAKS in env listing.
Solution (first that came to my mind)
I can't tell at the moment what is real impact on bash-completion feature after following solution is applied and of course SublimeREPL hopefully should be fixed accordingly. Please comment my answer to fill in missing knowledge.
We may want to remove disturbing characters to get rid of the error.
First let's identify those characters
$ echo -n "${COMP_WORDBREAKS}" | od -t x1c
will output
0000000 20 09 0a 22 27 3e 3c 3b 7c 26 28 3a
\t \n " ' > < ; | & ( :
0000014
so we have three to remove. The simplest way is to add to your .bashrc following line:
COMP_WORDBREAKS="${COMP_WORDBREAKS#???}"
Voila! No more error message.
My final thought is about removed characters. I'm not fully in how bash-completion works and I'm aware of that modifying COMP_WORDBREAKS can affect other scripts using it. For now you can always change it ad-hoc.
I hope this helped.
Cheers
回答3:
Found it. Fixed it. SublimeREPL assumes that running getenv_command will produce SOLELY the output from running env, and every line will contain an equals sign. But my .bash_profile echos some stuff to stdout.
The solution was to wrap my .bash_profile output in a
if [[ $- == *i* ]]
to not produce extra output besides the executed command.
回答4:
TLDR;
Replace:
env = dict(line.split('=', 1) for line in lines)
in ~/.config/sublime-text-3/Packages/SublimeREPL/repls/subprocess_repl.py
with
env = dict(line.split('=', 1) for line in lines if '=' in line)
(Thanks @MichaelOhlrogge for the shorter syntax)
Why this works
@develucas's solution helped me solve my issue. I didn't have the problem he was describing, but his investigation helped.
In my case, the login shell had a greeting. So, bash --login -c env
(the command specified in SublimeREPL.sublime-settings
file under the getenv_command
option) was printing something like this:
Hello, parth!
USER=parth
SHELL=/bin/bash
.
.
.
It turns out that SublimeREPL uses the output of this command to load the environment variables - as mentioned in the comment above the getenv_command
setting:
// On POSIX system SublimeText launched from GUI does not inherit
// a proper environment. Often leading to problems with finding interpreters
// or not using the ones affected by changes in ~/.profile / *rc files
// This command is used as a workaround, it's launched before any subprocess
// repl starts and it's output is parsed as an environment
"getenv_command": ["/bin/bash", "--login", "-c", "env"],
The code that parses this output is like this (in the ~/.config/sublime-text-3/Packages/SublimeREPL/repls/subprocess_repl.py
file for ST3):
def getenv(self, settings):
"""Tries to get most appropriate environent, on windows
it's os.environ.copy, but on other system's we'll
try get values from login shell"""
getenv_command = settings.get("getenv_command")
if getenv_command and POSIX:
try:
output = subprocess.check_output(getenv_command)
lines = output.decode("utf-8", errors="replace").splitlines()
env = dict(line.split('=', 1) for line in lines)
return env
except:
import traceback
traceback.print_exc()
error_message(
"SublimeREPL: obtaining sane environment failed in getenv()\n"
"Check console and 'getenv_command' setting \n"
"WARN: Falling back to SublimeText environment")
# Fallback to environ.copy() if not on POSIX or sane getenv failed
return os.environ.copy()
The env = dict(line.split('=', 1) for line in lines)
line causes an issue, because the first line in the bash --login -c env
output has no =
. So I modified this line to ignore the lines that don't have an =
sign:
env = dict(line.split('=', 1) for line in lines if '=' in line)
And this solved the issue for me. Don't forget the restart Sublime Text after modifying this file.
回答5:
changing COMP_WORDBREAKS does not work for me ...
i'm using ST2, and the exception was thrown at check_output().
also, name completions at the command line fails, after changing COMP_WORDBREAKS.
in my case, i changed subprocess_repl.py's env() method:
[wind]$ diff subprocess_repl.py.20151117.173317 subprocess_repl.py
160c160,161
< updated_env = env if env else self.getenv(settings)
---
> # updated_env = env if env else self.getenv(settings)
> updated_env = env if env else os.environ.copy()
[wind]$
would be interesting to find out why the problem started appearing suddenly ...
hth,cheers,
sam
回答6:
The answer from @develucas mostly works for me with ST3 with OSX El Capitan except I had to put
export COMP_WORDBREAKS="${COMP_WORDBREAKS#???}"
Note the export. However, if I do this, tab completion no longer works.
回答7:
I had the same problem, it was my .bash_profile
that had some utility outputs, such as a welcome message etc.
These outputs are parsed by SublimeREPL to try to extract environment variables from the output of the env
command, and the extraneous text lines mixed together provoked the error.
(I'd like to make a PR to SublimeREPL to try to make that phase more robust, it should not depend on particular .bash_profile
implementations!)