python 如何在不指定文件扩展名的情况下运行python脚本(跨平台解决方案)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2347042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:24:19  来源:igfitidea点击:

How to run a python script without specifying the file extension (cross platform solution)?

pythonbatch-fileshellcmdwrapper

提问by sorin

Let's say that we have a Python script do.pyand we want to be able to call it without extension, like door ./do.

假设我们有一个 Python 脚本do.py,我们希望能够在没有扩展名的情况下调用它,例如do./do

If we rename the file from do.pyto doand assure we have a valid shebang line it will work for all platforms but Windows. On Windows there is no way of executing file without extension.

如果我们将文件重命名为do.pytodo并确保我们有一个有效的 shebang 行,它将适用于除 Windows 之外的所有平台。在 Windows 上,无法执行没有扩展名的文件。

On Windows, if we keep the original file extension we'll be able to call the script without the full name because the Python installer registers the .pyextension as an executable one.

在 Windows 上,如果我们保留原始文件扩展名,我们将能够在没有全名的情况下调用脚本,因为 Python 安装程序将.py扩展名注册为可执行文件。

It looks that we need to deliver the same script under two different names in order to be call it on Windows and non-Windows environments. I really do not like this and I'm looking for a solution without this redundancy.

看起来我们需要以两个不同的名称交付相同的脚本才能在 Windows 和非 Windows 环境中调用它。我真的不喜欢这样,我正在寻找没有这种冗余的解决方案。

Another common approach on this is to add a do.cmdwrapper batch file that is calling the original do.pyfile. This has at least one major issue: it does break the Ctrl+C / Ctrl+Breakbecause there is no way to prevent cmd.exefrom prompting you with Terminate batch job? (Y/N)message.

另一种常见的方法是添加一个do.cmd调用原始do.py文件的包装批处理文件。这至少有一个主要问题:它确实打破了 Ctrl+C / Ctrl+Break因为没有办法阻止cmd.exe提示您终止批处理作业?(是/否)消息。

If we are about to use a wrapper we need to be sure that:

如果我们要使用包装器,我们需要确保:

  • return the errorcode (errorlevel) returned by the original script
  • it will not change the environment
  • it will reuse the same console (no new windows)
  • doesn't interfere with STDOUT, STDIN or STDERR
  • be friendly with Ctrl-C (no prompts)
  • 返回原脚本返回的错误码(errorlevel)
  • 它不会改变环境
  • 它将重用相同的控制台(没有新窗口)
  • 不干扰 STDOUT、STDIN 或 STDERR
  • 对 Ctrl-C 友好(无提示)

I suppose the optimal solution is still to use a wrapper. Batch won't work, native executable would add a lot of complexity so probably a wrapper wrote in python itself would do.

我想最佳解决方案仍然是使用包装器。批处理不起作用,本机可执行文件会增加很多复杂性,因此用 Python 本身编写的包装器可能会这样做。

采纳答案by sorin

So far I came up with this solution that seams to work. Create a file yourname.pywith this content:

到目前为止,我想出了这个接缝工作的解决方案。创建一个yourname.py包含以下内容的文件:

import os, sys
filename = os.path.splitext(os.path.basename(sys.argv[0]))[0]
if not os.path.exists(filename):
    # filename does not exists, we will emulate cmd behaviour
    sys.stderr.write("'%s' is not recognized as an internal or external command,\noperable program or batch file." % filename)
    sys.exit(9009)
ret = os.system("python %s %s" % (
        filename,
        " ".join(sys.argv[1:])
        ))
exit(ret)

回答by RoMa

On windows i added the '.py' extension to the 'PATHEXT' environment variable and that works for me - if the .py file is stored in an directory that is part of the 'PATH' environment variable.

在 Windows 上,我将 '.py' 扩展名添加到了 'PATHEXT' 环境变量中,这对我有用 - 如果 .py 文件存储在作为 'PATH' 环境变量一部分的目录中。

C:\>echo %PATHEXT%
.COM;.EXE;.BAT;.CMD;.PY;.JS;.JSE

回答by Jason

Write your main Python module with a .pyextension. Set up PATHEXTcorrectly, and it will run on Windows without having to type the extension.

.py扩展编写你的主要 Python 模块。PATHEXT正确设置,它将在 Windows 上运行而无需键入扩展名。

On Unix, write a second Python program that simply imports the first, using she-bang syntax. No extension on this file - it's a shell script. Like this:

在 Unix 上,编写第二个 Python 程序,使用 she-bang 语法简单地导入第一个。此文件没有扩展名 - 它是一个 shell 脚本。像这样:

#!/usr/bin/env python
import do

This will have the effect of importing do.py.

这将具有导入do.py.

Only doneeds to be marked as executable for Unix. do.pyis a module in that environment.

do需要标记为 Unix 的可执行文件。 do.py是那个环境中的一个模块。

When you import a module, the code in the module is run once.

导入模块时,模块中的代码会运行一次。

It doesn't completely remove redundancy, but it's close. And it is probably the best solution possible for cross-platform scripting.

它并没有完全消除冗余,但已经接近了。它可能是跨平台脚本的最佳解决方案。

回答by AndiDog

You can use distutils to install scripts into the Python installation (the easy_install tool is installed like that, for example).

您可以使用 distutils 将脚本安装到 Python 安装中(例如,easy_install 工具就是这样安装的)。

For Windows, you can use py2exeto create a script that can be executed without file extension. On Linux you can simply use a file without extension, but including a shebang line.

对于 Windows,您可以使用py2exe创建一个无需文件扩展名即可执行的脚本。在 Linux 上,您可以简单地使用没有扩展名的文件,但包括一个 shebang 行。

回答by ghostdog74

you can always call your script with the Python interpreter. You get the same consistency in *nix, when you use the interpreter.

您始终可以使用 Python 解释器调用您的脚本。当您使用解释器时,您在 *nix 中获得相同的一致性。

Windows

视窗

c:\> python c:\path\to\myscript 

*nix

*尼克斯

$ python /path/to/myscript

If its not what you want, then i am mis-interpreting your question.

如果它不是你想要的,那么我误解了你的问题。

回答by Hugo

Jason's answeris clearer and simpler, but a generic version gets the module name from the filename:

Jason 的回答更清晰、更简单,但通用版本从文件名中获取模块名称:

#!/usr/bin/env python
import importlib, os, sys
importlib.import_module(os.path.basename(sys.argv[0]))

Having said that, I prefer Jason's where it's immediately clear what's going on:

话虽如此,我更喜欢杰森的,它可以立即清楚发生了什么:

#!/usr/bin/env python
import do