Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不指定文件扩展名的情况下运行python脚本(跨平台解决方案)?_Python_Batch File_Shell_Cmd_Wrapper - Fatal编程技术网

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

如何在不指定文件扩展名的情况下运行python脚本(跨平台解决方案)?,python,batch-file,shell,cmd,wrapper,Python,Batch File,Shell,Cmd,Wrapper,假设我们有一个Python脚本do.py,我们希望能够在不扩展的情况下调用它,比如do或/do 如果我们将文件从do.py重命名为do,并确保我们有一个有效的shebang行,它将适用于除Windows以外的所有平台。在Windows上,无法执行没有扩展名的文件 在Windows上,如果保留原始文件扩展名,我们将能够调用脚本而不使用全名,因为Python安装程序将.py扩展名注册为可执行扩展名 看起来,我们需要用两个不同的名称交付相同的脚本,以便在Windows和非Windows环境中调用它。我

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

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

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

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

另一种常见的方法是添加一个调用原始
do.py
文件的
do.cmd
包装批处理文件。这至少有一个主要问题:它会中断Ctrl+C/Ctrl+break,因为无法阻止
cmd.exe
提示您使用

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

  • 返回原始脚本返回的错误代码(errorlevel)
  • 它不会改变环境
  • 它将重用同一控制台(无新窗口)
  • 不干扰标准输出、标准输入或标准输出
  • 友好地使用Ctrl-C(无提示)

我认为最佳的解决方案仍然是使用包装器。批处理不起作用,本机可执行文件会增加很多复杂性,所以用python编写的包装器可能就可以了。

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

窗户

c:\> python c:\path\to\myscript 
*尼克斯


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

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


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

到目前为止,我提出了这个解决方案,它可以正常工作。创建一个包含以下内容的文件
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)

在windows上,我向“PATHEXT”环境变量添加了“.py”扩展名,如果.py文件存储在作为“PATH”环境变量一部分的目录中,则该扩展名对我有效

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

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

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

#!/usr/bin/env python
import do
这将产生导入
do.py
的效果

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

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

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

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

#!/usr/bin/env python
import importlib, os, sys
importlib.import_module(os.path.basename(sys.argv[0]))
话虽如此,我还是更喜欢杰森的作品,因为它能立即清楚地说明发生了什么:

#!/usr/bin/env python
import do

也许答案就在于“为什么你想不加扩展就称之为”这个问题?哇,这么多的工作没有真正的好处。do.py怎么了?这完全是跨平台的,没有任何工作。对于那些想知道:没有扩展意味着我们隐藏了实现细节的人:例如,如果明年我想用Ruby脚本替换当前的Python脚本,我不希望需要更改对脚本的所有调用。另一个不太重要的参数:从命令行写入的代码更少。在Windows上,如果我们保留原始文件扩展名,我们将能够调用脚本而不使用全名,因为Python安装程序将
.py
扩展名注册为可执行扩展名,而不是true。注册扩展名不允许在不提供扩展名的情况下调用脚本。为此,您还需要按照RoMa的建议将扩展名添加到
PATHEXT
环境变量中。如果您安装了脚本,则可以使用
python-m moduleName
运行它。这也是跨平台的。这不是他想要的。他希望像系统中的任何其他可执行文件一样运行它—在命令行中只指定可执行文件(脚本)的名称。这是OP给出的对称解决方案,但它更简单,因此似乎更好。相关:这在命令shell中对我有效,但在运行提示中,我不得不添加一个伪“python_script.exe”注册表的键-HKLM\Software\Microsoft\Windows\CurrentVersion\App path\然后我将默认值设置为python_script.py path,然后我就可以在运行提示中键入“python_script”。但这在非Windows上如何工作?我可以在没有扩展名的情况下键入
do
#!/usr/bin/env python
import do