10

在 bash 中,我们可以:

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

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

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

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

谢谢。

4

6 回答 6

17

您可以使用混合技术,此解决方案也适用于 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#
命令是一个冒号:,表示一个标签,并且从不打印带标签的行。
然后最后一个插入符号只是将下一行附加到标签行,因此批处理看不到该'''行。

于 2013-07-04T11:12:08.423 回答
17

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

@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 ...
于 2015-04-26T17:44:27.640 回答
1

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

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

或使用 windows cmd 根本不解释的简单引号:

python -c print('Hi')
于 2019-01-23T19:28:58.363 回答
0

我知道这样做的唯一方法是从批处理文件中调用 Python 脚本,如下所示:

@echo off
REM whatever other code
python python_script.py
REM rest of batch file...
于 2013-07-04T10:32:57.673 回答
0

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

于 2013-07-04T10:11:45.527 回答
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 脚本...

于 2016-10-02T09:24:25.523 回答