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

sor*_*rin 9 python shell cmd batch-file wrapper

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

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

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

看起来,我们需要为了要调用它在Windows和非Windows环境下的两个不同的名字提供相同的脚本.我真的不喜欢这个,我正在寻找没有这种冗余的解决方案.

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

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

  • 返回原始脚本返回的错误代码(errorlevel)
  • 它不会改变环境
  • 它将重用相同的控制台(没有新窗口)
  • 不会干扰STDOUT,STDIN或STDERR
  • 与Ctrl-C友好(没有提示)

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

小智 5

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

C:\>echo %PATHEXT%
.COM;.EXE;.BAT;.CMD;.PY;.JS;.JSE
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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

#!/usr/bin/env python
import do
Run Code Online (Sandbox Code Playgroud)

这样就可以达到导入的效果了do.py

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

当您导入模块时,模块中的代码将运行一次。

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


sor*_*rin 2

到目前为止,我想出了这个可行的解决方案。创建一个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)
Run Code Online (Sandbox Code Playgroud)