如何在批处理脚本中嵌入Python代码

问题描述 投票:0回答:6

在 bash 中,我们可以:

python - << EOF
import os
print 'hello'
EOF

在 bash 脚本中嵌入 python 代码片段。

但是在 Windows 批处理中,这不起作用 - 虽然我仍然可以使用 python -c 但这需要我将代码压缩成一行,这是我试图避免的事情。

有没有办法在批处理脚本中实现这一点?

谢谢。

python windows bash batch-file
6个回答
21
投票

甚至更高效,而且它将所有命令行参数传递给脚本并返回退出代码:

@SETLOCAL ENABLEDELAYEDEXPANSION & python -x "%~f0" %* & EXIT /B !ERRORLEVEL!
# Your python code goes here...

以下是正在发生的事情的详细情况:

  • @
    防止打印脚本行
  • SETLOCAL ENABLEDELAYEDEXPANSION
    允许!错误级别!在Python脚本运行之后进行评估
  • &
    允许在同一行运行另一个命令(类似于 UNIX 的
    ;
  • python
    运行 python 解释器(必须位于 %PATH% 中)
  • -x
    告诉 python 忽略第一行(运行 python -h 了解详细信息)
  • "%~f0"
    扩展为当前正在执行的批处理脚本的完全限定路径(参数 %0)。如果路径包含空格,则会被引用
  • %*
    扩展传递给脚本的所有参数,有效地将它们传递给 python 脚本
  • EXIT /B
    告诉 Windows Batch 仅从当前批处理文件退出(仅使用
    EXIT
    将导致调用解释器退出)
  • 运行后,
  • !ERRORLEVEL!
    扩展为上一个命令的返回代码。用作
    EXIT /B
    的参数,它会导致批处理脚本退出并返回从 python 解释器收到的返回码

注意:如果您的 python 二进制文件不在 PATH 中或位于非标准位置,您可能需要将“python”更改为其他内容。例如:

@"C:\Path\To\Python.exe" -x ...

20
投票

您可以使用混合技术,该解决方案也适用于 Python

import

1>2# : ^
'''
@echo off
echo normal 
echo batch code
echo Switch to Python
python "%~f0"
exit /b
rem ^
'''
print("This is Python code")

批处理代码位于多行字符串中

'''
,因此对于 Python 来说这是不可见的。 批处理解析器看不到 Python 代码,因为它之前就退出了。

第一行是关键。
它对批处理有效,对 Python 也有效!
在Python中,这只是一个无意义的比较

1>2
,没有输出,该行的其余部分是
#
的注释。

对于批处理

1>2#
是将流
1
重定向到文件
2#

命令是冒号
:
,这表示标签和标记行永远不会打印。
然后最后一个插入符号只需将下一行附加到标签行,因此批处理不会看到
'''
行。


1
投票

对于一个简单的命令:Windows cmd 提示符仅理解双引号,因此您可以将它们加三倍以使其与

-c
选项一起使用:

python -c print("""Hi""")

或使用 Windows cmd 根本无法解释的简单引号:

python -c print('Hi')

0
投票

摆脱必须立即在批处理文件中指定 python 脚本的想法。将 python 代码放在一个单独的文件中,然后只需从 Windows 批处理文件中启动 python 下的单独文件即可。


0
投票

我知道执行此操作的唯一方法是从批处理文件中调用 Python 脚本,如下所示:

@echo off
REM whatever other code
python python_script.py
REM rest of batch file...

0
投票
@echo off
setlocal EnableDelayedExpansion

set "fTmpPy=%TEMP%\~fTmp.py"

call :getLine "::python_beg" "::python_end" > "!fTmpPy!"

python "!fTmpPy!"

pause
exit /b 0

:getLine <beg str> <end str>
  set "bBegEnd=0"
  for /f "usebackq delims=" %%l in ("%~f0") do (
    if !bBegEnd! equ 1 (
      if "%%l" equ "%~2" ( exit /b 0 )
      setlocal DisableDelayedExpansion
      echo %%l
      endlocal
    ) else (
      if "%%l" equ "%~1" ( set "bBegEnd=1" )
    )
  )
exit /b 0

endlocal

::mark is unique - one character or string
::begin mark must be
::end mark is optional if it is on eof

::python_beg
print( 'Hello, world!' )
::python_end

可以包含任何字符或字符串,但只能包含“!”感叹是例外。 '!'用于变量,因此您必须设置“DisableDelayedExpansion”。最后,您必须设置“endlocal”。仅此而已。

您可以将此例程用于任何脚本或任何文档。即使cmd脚本...

© www.soinside.com 2019 - 2024. All rights reserved.