4

让我们在 Windows 批处理脚本中考虑这个 FOR 循环:

D:\MiLu\Dev\C++\temp :: type string.bat
@ECHO OFF
FOR %%a IN (%*) DO ECHO %%a

它一一呼应了所有的论点。真的吗?

D:\MiLu\Dev\C++\temp :: string.bat foo.obj bar.obj CPPFLAGS=/EHsc
foo.obj
bar.obj
CPPFLAGS
/EHsc

它不仅在空格(好)上拆分命令行参数,而且在 =(不好)上拆分命令行参数。我怎样才能防止这种情况发生?

我想要实现的很简单:一个围绕 NMAKE.exe 的包装器,它指定/nologonmake 以及 - 这就是问题 - 通过环境变量 CFLAGS 和 CPPFLAGS 到编译器,同时包括提供的 CFLAGS 和 CPPFLAGS 的任何设置在命令行上。

换句话说,即使没有脚本,我也希望将脚本添加/nologo到 CFLAGS 和 CPPFLAGS 的命令行输入中。总是/nologo!不要用你的标志惹恼我,编译器同志!

更新

这是我根据迈克的回答得出的结论:

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

FOR %%a IN (%*) DO (
    SET var1=%%a
    ECHO %%a - !var1! - !var1:~0,1!
    IF "!var1:~0,1!" EQU "/" (
        ECHO gefunden: %%a !var1!
    )
)

明天继续……

更新 2

好的,鉴于明天已经到来,我不妨继续……所以这是一个可行的解决方案,自豪地提出。随意评论如何改进它。

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

SET files=
SET   CFLAGS=/nologo %CFLAGS%
SET CPPFLAGS=/nologo %CPPFLAGS%

SET state=normal
FOR %%a IN (%*) DO (
    SET curarg=%%a
    REM ECHO %%a - !curarg! - !curarg:~0,1!
    IF /I "%%a" EQU "CFLAGS" (
        SET state=expecting_cflags
    ) ELSE IF /I "%%a" EQU "CPPFLAGS" (
        SET state=expecting_cppflags
    ) ELSE (
        IF "!curarg:~0,1!" EQU "/" (
            REM ECHO gefunden: %%a !curarg!
            IF "!state!" EQU "expecting_cflags" (
                REM ECHO expecting_cflags
                SET CFLAGS=!CFLAGS! !curarg!
            ) ELSE IF "!state!" EQU "expecting_cppflags" (
                REM ECHO expecting_cppflags
                SET CPPFLAGS=!CPPFLAGS! !curarg!
            ) ELSE (
                ECHO Logikfehler >&2
            )
        ) ELSE (
            SET files=!files! !curarg!
        )
        SET state=normal
    )
)
ECHO Dateien:  !files! >&2
ECHO CFLAGS:   !CFLAGS! >&2
ECHO CPPFLAGS: !CPPFLAGS! >&2
:: ECHO ON
nmake /nologo %files% CFLAGS="%CFLAGS%" CPPFLAGS="%CPPFLAGS%"
ENDLOCAL
4

3 回答 3

2

您是否尝试过以下操作?

string.bat foo.obj bar.obj "CPPFLAGS=/EHsc"

如果您CPPFLAGS自己附加参数,请尝试将其括在引号中。

参考:http ://www.robvanderwoude.com/parameters.php

于 2012-01-30T00:31:57.633 回答
2

解决该问题的一种方法是指定“CPPFLAGS=/EHsc”,然后在循环中使用 %%~a 去掉双引号。

解决此问题的另一种方法是检查 %%a 的第一个字符,如果是 a,则在其/前面加上 a =。为了实现这一点,您需要setlocal enabledelayedexpansion将 %%a 分配给一个变量,然后使用 %variable:~1,1% 表示法提取第一个字符,以便您可以将其与/. 有关此表示法的更多信息,请键入help set

更新(在 OP 更新后)

以下片段似乎可以工作,它比您解决方案中的相应片段更简单,并且它不包含任何硬编码的参数名称,因此它更通用:

SET allargs=
FOR %%a IN (%*) DO (
    SET curarg=%%a
    IF "!curarg:~0,1!" EQU "/" (
        SET allargs=!allargs!=!curarg!
    ) ELSE (
        SET allargs=!allargs! !curarg!
    )
)
ECHO !allargs!
于 2012-01-30T00:37:24.063 回答
2

您可以for /f在循环中使用以强制按空格而不是按等号拆分参数列表。尝试这样的事情:

@echo off
setlocal enabledelayedexpansion

set params=%*

:loop
for /f "usebackq tokens=1,*" %%A in ('!params!') do (
  echo %%A
  set params=%%B
)
if not "!params!"=="" goto loop

endlocal
于 2012-01-30T09:55:17.647 回答