在 bash 中,我们可以:
python - << EOF
import os
print 'hello'
EOF
在 bash 脚本中嵌入 python 代码片段。
但是在 Windows 批处理中,这不起作用 - 虽然我仍然可以使用 python -c 但这需要我将我的代码合并为一行,这是我试图避免的事情。
有没有办法在批处理脚本中实现这一点?
谢谢。
在 bash 中,我们可以:
python - << EOF
import os
print 'hello'
EOF
在 bash 脚本中嵌入 python 代码片段。
但是在 Windows 批处理中,这不起作用 - 虽然我仍然可以使用 python -c 但这需要我将我的代码合并为一行,这是我试图避免的事情。
有没有办法在批处理脚本中实现这一点?
谢谢。
您可以使用混合技术,此解决方案也适用于 python 导入。
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#
。
该命令是一个冒号:
,表示一个标签,并且从不打印带标签的行。
然后最后一个插入符号只是将下一行附加到标签行,因此批处理看不到该'''
行。
效率更高,而且它将所有命令行参数传递给脚本并从脚本返回退出代码:
@SETLOCAL ENABLEDELAYEDEXPANSION & python -x "%~f0" %* & EXIT /B !ERRORLEVEL!
# Your python code goes here...
以下是正在发生的事情的细分:
@
防止脚本行被打印SETLOCAL ENABLEDELAYEDEXPANSION
允许 !ERRORLEVEL! 在 python 脚本运行后进行评估&
允许在同一行上运行另一个命令(类似于 UNIX 的;
)python
运行 python 解释器(必须在 %PATH% 中)-x
告诉 python 忽略第一行(运行 python -h 了解详细信息)"%~f0"
扩展为当前正在执行的批处理脚本的完全限定路径(参数 %0)。如果路径包含空格,则引用它%*
扩展传递给脚本的所有参数,有效地将它们传递给 python 脚本EXIT /B
告诉 Windows Batch 仅从当前批处理文件中退出(使用 justEXIT
会导致调用解释器退出)!ERRORLEVEL!
运行后扩展为上一个命令的返回码。用作 的参数EXIT /B
,它会导致批处理脚本以从 python 解释器接收的返回码退出注意:如果您的 python 二进制文件不在 PATH 中或位于非标准位置,您可能必须将“python”更改为其他内容。例如:
@"C:\Path\To\Python.exe" -x ...
对于一个简单的命令:Windows cmd 提示符仅理解双引号,因此您可以将它们加倍以使其与-c
选项一起使用:
python -c print("""Hi""")
或使用 windows cmd 根本不解释的简单引号:
python -c print('Hi')
我知道这样做的唯一方法是从批处理文件中调用 Python 脚本,如下所示:
@echo off
REM whatever other code
python python_script.py
REM rest of batch file...
摆脱必须立即在批处理文件中指定 python 脚本的想法。将 python 代码放在一个单独的文件中,然后在 python 下从 Windows 批处理文件启动单独的文件。
@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 脚本...