我想从 stdin 读取我需要创建的批处理文件的文件名。全部在一条生产线上,并使用管道。当我尝试时,cmd 在我输入名称之前正在创建.bat。
set /p filename= | copy NUL %a%.bat
这不是管道的工作方式。管道采用上一个命令的输出,并使其成为下一个命令的输入。您的 set /p filename=
命令不会生成任何输出,因此copy NUL %a%.bat
不会获得任何输入,但这无论如何都无关紧要,因为 copy
命令无论如何都不会接受任何输入。您的 copy NUL %a%.bat
命令会创建一个名为 .bat 的空文件,因为您尚未定义名为 a
的变量,因此%a%
会扩展为空字符串。
您要执行的操作需要两个命令:
set /p filename=
copy NUL %filename%.bat
作为批处理文件中的一行,使用
SET /p "filename=Filename ? "&CALL COPY NUL %%filename%% >nul
如果在提示符下输入此内容,请将%%
减少到%
请注意,>nul
会禁止显示file copied
消息。
为了补充Klitos Kyriacou的有用答案:
管道绝对不是正确的选择,但&
和&&
原则上可用于在一行上执行多个命令,因此您可能会想执行以下操作:
:: !! WRONG
set /p filename="" && copy NUL "%filename%.bat"
问题是变量引用%filename%
在命令行开始执行之前被展开。[1]
但是,如果您打开延迟扩展(通过 cmd /V
或,在带有 setlocal enabledelayedexpansion
的批处理文件中(这也使所有变量都在本地((,则可以执行此操作,假设您使用 !...!
来引用变量:
:: OK, assuming delayed expansion is on.
set /p filename="" && copy NUL "!filename!.bat"
[1] Magoo 的答案通过一个技巧解决了这个问题:call
有效地延迟扩展,但这要求%filename%
不要预先扩展,这就是为什么%%
加倍以产生文字%
字符的原因:%%filename%%
最初扩展到文字%filename%
,然后被call
解释为变量引用 - 此时变量已经有了它的值。
由于%
字符无法在命令行上转义,因此需要一种不同的方法:%filename^%
实现与上述相同的方法。