清理 DOSKEY 宏中的命令参数

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

假设我的

AutoRun
脚本中有以下内容:

@doskey cd = @( ^
    for /f usebackq^^ delims^^=^^ eol^^= %%a in (^
        '$* ' ^
    ) do @( ^
        if "%%~a"==" " ( ^
            if /i not "%%CD%%"=="%%USERPROFILE%%" ( ^
                chdir /d "%%USERPROFILE%%" ^&^& ^
                set "OLDPWD=%%CD%%" ^
            ) ^
        ) else if "%%~a"=="- " ( ^
            if /i not "%%CD%%"=="%%OLDPWD%%" ( ^
                chdir /d "%%OLDPWD%%" ^&^& ^
                set "OLDPWD=%%CD%%" ^
            ) ^
        ) else ( ^
            if /i not "%%CD%%"=="%%~a" ( ^
                chdir /d "%%~a" ^&^& ^
                set "OLDPWD=%%CD%%" ^
            ) ^
        ) ^
    ) ^
)

这应该是在

cd
中模仿 POSIX
cmd.exe
的行为,并且在大多数情况下效果很好:

C:\Users\user>cd C:\

C:\>cd

C:\Users\user>cd -

C:\>

然而,只需要一对不完整的单引号就可以让纸牌屋倒塌:

C:\>cd "
2> was unexpected at this time.

是否有一种内联清理宏输入的方法,以便它可以正确处理放错位置的引号?

我已经尝试/想到了以下内容:

  • 创造性地使用带有单引号的
    for /f
    - 您可以在提供的示例中看到:它在字符串比较期间不会中断参数列表,但
    "
    就是它所需要的
  • 将整个事情变成一个复合宏(即
    for /l (1, 1, 2)...
    最后与
    set args=,
    结合) - 不,不能从命令行上下文启用延迟扩展
  • 忽略
    $*
    并只使用
    $1
    $2
    等并希望最好 - 不能解决问题,因为DOSKEY在定界参数时不关心双引号并且不适用于
    chdir
    无论如何当命令扩展已启用,因为它不会将空格(或任何东西)视为分隔符
windows batch-file cmd chdir doskey
1个回答
0
投票

一种简单的方法是对某些代码也使用定义批处理文件。
宏在最后使用

set args=
,然后调用主代码的批处理文件。
使用这种技术,代码也更具可读性。

@echo off
REM *** Trampoline jump for function calls of the form ex. "C:\:function:\..\MyBatchFile.bat"
FOR /F "tokens=3 delims=:" %%L in ("%~0") DO goto :%%L


doskey cd=for %%# in ( 1 1 2) do @if %%#==2 ( "%~d0\:__cd:\..\%~pnx0" ) else set args=$*

exit /b

:__cd

setlocal EnableDelayedExpansion

for /F "delims=" %%a in (""!args!"") DO (
  endlocal
  if "%%~a"=="" (
      if /i not "%CD%"=="%USERPROFILE%" (
          chdir /d "%USERPROFILE%" && set "OLDPWD=%CD%"
      ) 
  ) else if "%%~a"=="-" (
       if /i not "%CD%"=="%OLDPWD%" (
            chdir /d "%OLDPWD%" && set "OLDPWD=%CD%"
       ) 
  ) else (
        if /i not "%CD%"=="%%~a" (
            chdir /d %%~a && set "OLDPWD=%CD%"
        )
  )
)

仅限Doskey:
但是如果你坚持只用 doskey 宏来解决它,你可以使用消失的插入符。

Line2 做的伎俩:

FOR %%^^^^ in ("") do
定义一个空的
%%^
FOR 元变量。

这用于

for /f "delims=" %%a in (^^""$*%%~^^"^")

%%~^^
转义下一个引号,但前提是
$*
包含不平衡的引号,并且在展开后
%%~^^
消失。
引号转义解决了
$*
中不平衡引号的问题,因为在
$*
中没有或平衡引号的情况下,它扩展为 一个平衡的引号字符串,但这甚至适用于
$*

中的不平衡引号
doskey cd=( ^
    FOR %%^^^^ in ("") do @for /f "delims=" %%a in (^^""$*%%~^^"^") do @( ^
        if "%%~a"=="" ( ^
            if /i not "%%CD%%"=="%%USERPROFILE%%" ( ^
                chdir /d "%%USERPROFILE%%" ^&^& ^
                set "OLDPWD=%%CD%%" ^
            ) ^
        ) else if "%%~a"=="-" ( ^
            if /i not "%%CD%%"=="%%OLDPWD%%" ( ^
                chdir /d "%%OLDPWD%%" ^&^& ^
                set "OLDPWD=%%CD%%" ^
            ) ^
        ) else ( ^
            if /i not "%%CD%%"=="%%~a" ( ^
                chdir /d %%~a  ^&^& ^
                set "OLDPWD=%%CD%%" ^
            ) ^
        ) ^
    ) ^
)
© www.soinside.com 2019 - 2024. All rights reserved.