【问题标题】:Writing a script that can be both piped to and given direct input编写一个既可以通过管道传输也可以直接输入的脚本
【发布时间】:2014-02-25 13:12:36
【问题描述】:

这是here 的后续问题,根据最初回答者的建议发布。

我正在尝试创建一个脚本,该脚本将 采用管道输入 并且 还可以直接从命令行输入。我写了两个脚本;第一个称为create,另一个称为edit。我在下面给出代码。

@echo off
REM create
if -%1-==-- (
    REM Piped
set /p name=
copy nul %name% > nul
echo %name%
) else (
    REM Not piped
copy nul %1 > nul
)

@echo off
REM edit
if -%1-==-- (
    REM Piped
set /p file=
start notepad++.exe %file%
) else (
    REM Not piped
start notepad++.exe %1
)

我添加了注释以澄清哪个是哪个,以及我的意图是什么。现在,正常输入(例如,如果我只是在命令提示符中键入 create foo.txt)工作正常,但是当我尝试管道时(例如,create foo.txt | edit)我得到了奇怪的行为,即编辑脚本试图在这个例子中打开一个与foo.txt 完全不同的文件!我错过了什么或做错了什么?

【问题讨论】:

    标签: windows shell scripting cmd pipe


    【解决方案1】:

    在批处理文件中,当执行到一行时,它会被解析然后执行。在解析时,行内的所有变量读取都将替换为其相应的值。

    这适用于行和块,其中块是括号中的所有行。块被读取、解析并获取变量读取替换为变量值之前执行块内的任何行。

    您在代码中看到的是变量%file% 在块内分配了它的值,然后,在同一个块内,您尝试读取变量值。但是由于所有的变量读取都被替换为进入块之前的值,所以无法获取更改后的值。

    要处理它,需要延迟扩展。当延迟扩展处于活动状态时,您可以向 cmd 指示一些变量读取应该延迟到执行该行的那一刻。你的代码应该是这样的

    @echo off
    setlocal enabledelayedexpansion
    REM create
    if -%1-==-- (
        REM Piped
        set /p name=
        copy nul !name! > nul
        echo !name!
    ) else (
        REM Not piped
        copy nul %1 > nul
    )
    
    @echo off
    setlocal enabledelayedexpansion
    REM edit
    if -%1-==-- (
        REM Piped
        set /p file=
        start notepad++.exe !file!
    ) else (
        REM Not piped
        start notepad++.exe %1
    )
    

    使用!var! sintax 访问需要延迟读取的变量。

    【讨论】:

      猜你喜欢
      • 2014-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多