1

是的,现在是 2021 年,我仍在使用 CMD shell 和批处理脚本来完成简单的任务。我最近刚刚尝试通过为(每个)CMD 提示会话自动运行我自己的初始化脚本来增强我的工作流程,其中还包括设置一堆 DOSKEY 宏。

所以这是与其他人所做的类似的设置。[1]

在新脚本出现奇怪问题后,我意识到,当从具有活动宏的修改后的 shell 执行时,DOSKEY 宏可以使用“SET /P”命令破坏批处理脚本中的交互式提示。

尝试这样的事情(在提示符下输入显示在 [] 之间的文本 + 按 <enter>):

@ECHO OFF
DOSKEY print=ECHO $*
SET /P var=Enter [print Hallo]:
ECHO var: %var%
EXIT /B 0

您将看到,prompt 变量包含由 DOSKEY 宏 ('ECHO Hallo') 创建的命令提示符。

通常 DOSKEY 不应该在批处理文件 [2][3] 中工作/可用,因为它仅适用于交互式提示 [4]。但是“SET /P”似乎算作一个交互式shell,所以DOSKEY替换了所有输入的内容,以定义的宏关键字开头。

好吧,这对我来说似乎是一个错误(DOSKEY 现在已经 30 岁了,顺便说一句 [6]),但我在网上找不到任何关于这个问题的信息。所以,我在想如何解决这个问题。由于宏不能轻易停用/删除 [5],因此从任何会提示的批处理文件中修复此问题会很麻烦。

我的 init-script 也只为交互式会话运行,所以当您直接(单独)运行批处理脚本时,这不是问题。

在装有“Windows 7 Home Premium SP1”的机器上测试。

资料来源:

  1. https://gist.github.com/steve-jansen/5118149
  2. https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/doskey
  3. https://ss64.com/nt/doskey.html
  4. https://www.dostips.com/forum/viewtopic.php?t=1937#p8379
  5. 如何删除doskey宏?
  6. https://en.wikipedia.org/wiki/DOSKEY
4

2 回答 2

1

我看不到完美的解决方案,但由于 DOSKEY 用于“交互式外壳”,因此最简单的解决方案也是交互式的:

在运行任何使用提示的批处理之前,只需通过 ALT+F10 [2][3] 手动清除所有宏。

您还可以备份和恢复当前定义的宏集,例如,如果您在会话期间添加了一些宏。

DOSKEY /macros >%TEMP%\doskey-macros.txt
[Pressing ALT+F10]
batch_that_does_prompts.cmd
DOSKEY /macrofile=%TEMP%\doskey-macros.txt
于 2021-01-23T06:54:34.347 回答
0

您可以使用另一个窗口set /p,没有加载doskey:

@echo off
FOR /F "tokens=3 delims=:" %%# in ("%~0") do goto :%%#

doskey x=XXXXXXXXXXX

echo Test1: Shows the problem
call :subTest

echo Test2: No problem
start "" /wait cmd /c %~d0\:subTest:\..\%~pnx0 pause
echo end
exit /b

:subTest
set "var=empty"
set /p var=[Please enter a single 'x' and press enter]:
set var
%~1
exit /b

或者你“卸载”所有宏

@echo off
doskey x=XXXXXXXXXXX

echo Test1: Shows the problem
call :subTest

echo Test2: No problem
REM Save macros
DOSKEY /macros >%TEMP%\doskey-macros.txt
call :unload_macros
call :subTest

REM Restore macros
DOSKEY /macrofile=%TEMP%\doskey-macros.txt

echo end
exit /b

:unload_macros
for /F "delims==" %%M in ('doskey /macros') do (
    doskey %%M=
)
exit /b
于 2021-01-23T14:47:44.880 回答