why does setting an initial environment using env

2019-05-22 19:04发布

问题:

I have a test script, e.g. "test.py", and I want to make it so that it executes with a particular environment variable set before the script begins:

#!/usr/bin/env TEST=anything python

print "Hello, world."

Running this normally works as expected:

$ python test.py 
Hello, world.

However, if I run it as a program:

$ chmod +x test.py
$ ./test.py 

The string is never printed, instead the execution just stalls and "top" reports a process called "test.py" which is using 100% CPU.

This only happens on my Ubuntu machine, seems to be fine on OS X.

The reason is that eventually I want to make a particular script always run in a 32-bit Python by setting:

#!/usr/bin/env VERSIONER_PYTHON_PREFER_32_BIT=yes python

at the top of the file. However this is a no-go if it means the script won't execute on Linux machines. I found there is a similar effect no matter what the specified environment variable is called. However, if there is no environment variable set:

#!/usr/bin/env python

print "Hello, world."

The script runs just fine:

$ ./test.py 
Hello, world.

Is this a bug in Python or in env, or am I doing something wrong?

回答1:

On Linux,

#!/usr/bin/env TEST=anything python

passes TEST=anything python as one argument to env. So env will not process the argument properly.

The bottom line is you can only put one command after env on the shebang line, all else will at best be ignored.

From the Wikipedia entry on Shebang:

Another portability problem is the interpretation of the command arguments. Some systems, including Linux, do not split up the arguments[24]; for example, when running the script with the first line like,

#!/usr/bin/env python -c

That is, python -c will be passed as one argument to /usr/bin/env, rather than two arguments. Cygwin also behaves this way.



回答2:

I doubt /usr/bin/env VERSIONER_PYTHON_PREFER_32_BIT=yes python is going to run properly.

Instead, try setting the environment variables with Python:

import os

os.environ['VERSIONER_PYTHON_PREFER_32_BIT'] = 'yes'


回答3:

You'll probably need to forget about VERSIONER_PYTHON_PREFER_32_BIT, at least on Linux. On Mac, you could use a shell wrapper for it.

Then on Linux, you'll probably need to reinvent VERSIONER_PYTHON_PREFER_32_BIT using a small stub python script or bash script or something, hinging on something like the following:

>>> import platform
>>> platform.machine()
'x86_64'
>>> platform.processor()
'x86_64'


标签: python shell env