使用 /usr/bin/env 为什么会破坏我的 Python 导入?

6

在OSX 10.8.2上,使用Python 2.7.3。我正在编写一个脚本,其中导入了markdown模块。为了实现可移植性,我使用了#!/usr/bin/env python shebang。当我直接通过./myscript.py arg1在shell中运行脚本时,它可以正常运行。

但是,当我从不在登录状态的shell之外运行脚本时,例如通过AppleScript do shell script "/path/to/myscript.py " & quoted form of arg1,它会失败并显示以下错误信息:

myscript.py", line 8, in <module>
    import markdown
ImportError: No module named markdown

我觉得这可能是与shebang有关的问题,所以我将shebang更改为我的python位置#!/usr/local/bin/python,确实脚本正常工作了。

所以我的问题有两个:

  1. 为什么使用/usr/bin/env python会破坏我的导入?
  2. 如何避免这个问题而不必使用/usr/local/bin/python

我认为问题不在于使用/usr/bin/env python,而是使用了非登录shell。我猜测在这样的shell中,/usr/local/bin没有被添加到PATH中,或者至少没有在/usr/bin之前,这就解释了为什么后者会选择python。你是否在bash配置文件中更改了PATH - millimoose
我遗漏的一点是,#!/usr/bin/env python#!/usr/local/bin/python在TextWrangler中都能够完美运行,并且在终端中运行时产生了相同的结果。只有从AppleScript中调用它才会产生错误(rodrigo是正确的)。虽然TextWrangler和Terminal都给了我相同的结果,但我可以通过在AppleScript编辑器中运行do shell script "(echo 'import sys'; echo 'print sys.path';) | /usr/bin/env python"来看到它们之间的区别。do shell script "which python"甚至更容易些。 - n8henrie
2个回答

5
#!/usr/bin/env python 表示“在$PATH路径下查找python并运行它”,就好像shell要查找它一样。所以,由于你得到了不同的结果,你可能正在使用不同的pythons。
要检查,请看看运行/usr/local/bin/python/usr/bin/env python 是否会给出相同的pythons。你还可以使用type -a python来查找 $PATH 上的每个python。在我的系统中,type -a python 的输出如下:
python is /opt/local/bin/python
python is /usr/bin/python
python is /usr/local/bin/python

第一个安装程序是通过MacPorts安装的。

无论如何,正如Rodrigo所指出的那样,直接启动可能没有使用您期望的$PATH。这意味着使用/usr/bin/env不能起作用。


你的回答解释了问题的本质,但没有说明如何解决它。 - jscs
1
最简单的解决方案是使用 #!/usr/local/bin/python 或将您的 AppleScript 更改为 do shell script "/usr/local/bin/python /path/to/myscript.py " & quoted form of arg1 - Mike DeSimone
我很感激这些信息。还有两个因素导致了我的困惑:一个是/usr/local/bin/python和/usr/bin/env python似乎给了我完全相同的结果——我猜测这是因为我无论如何都是从登录shell运行命令。另一个可能是我在两个位置都安装了相同版本的Python,因为运行这些命令并没有给我python的路径,只有版本号。 - n8henrie
还要感谢您的回答。通过在AppleScript中识别正确的Python,我能够保持Python脚本中的#!/usr/bin/env python,这意味着该脚本在我的系统上是可用的,并且对其他人也是可移植的。完美! - n8henrie
我并不是指“同时使用/usr/local/bin/python和/usr/bin/env python来运行程序”; 我的意思是直接运行它们,看看报告了哪个版本号和构建日期。 - Mike DeSimone
我已经完成了。正如我所说,它们给了我相同的版本号(以及构建日期)。 n8henrie:~ n8henrie$ /usr/bin/env python Python 2.7.3 (default, Feb 25 2013, 14:21:33) :: n8henrie:~ n8henrie$ /usr/local/bin/python :: Python 2.7.3 (default, Feb 25 2013, 14:21:33) - n8henrie

1

看起来你的登录 shell 中的 PATH 环境变量与 AppleScript 进程中的不同。

我猜测你有一个 .profile 文件或类似文件,其中包含以下行:

PATH=/usr/local/bin:$PATH

但是只有在打开shell时才会执行该文件,而不是从其他进程中执行。显然,您在/usr/bin/python中有一个不具备markdown模块的不同版本的Python。


你的回答解释了问题的本质,但没有说明如何解决它。 - jscs
@JoshCaswell:你说得没错。最好的解决方案是在系统范围内或至少用户范围内更改路径,以便所有用户进程都具有相同的搜索路径。但我担心细节是系统特定的,而且楼主没有说他使用的是什么(可能是关于苹果的一些东西)。 - rodrigo
1
非常感谢您的解释。正如帖子开头所述,我正在使用OSX 10.8.2。我可能会尝试更改我的非登录shell路径。 - n8henrie
自从原始修订版以来,Python版本和操作系统一直是帖子中的第一句话。 - jscs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接