萝卜L

导航

CMD BATCH pipe / redirect / EOF signal V1.3

管道Pipe

A | B,同时(异步)开始A、B,设置B的输入流(0)为A的输出流(1)。
在A执行结束/返回/退出后,A的输出传递作为B的输入,执行B。"在A结束后",而非实时

  • 关于顺序的测试:

    >(ping 192.168.0.0 >nul & echo 1 >>&2)  | echo 2 >>&2
    2	;回车以上命令后立即输出
    1	;等待ping命令超时后,得到此输出
    
  • A|B中,AB为新环境,其中A独立B继承上文,即:

    >set var=a
    var=a
    >set var >&2 | echo >nul
    环境变量 var   没有定义			;独立新环境
    >echo %var% >&2 | echo >nul	;在解析时,展开为'echo a >&2 | echo >nul'
    a
    >echo >nul | set var
    var=a	;继承上文环境
    >echo >nul | set var >&2	;同上
    var=a
    >echo >nul | (set var)		;同上
    var=a
    >echo >nul | (<&3 set var)	;在管道中,在括号内设置输入输出流改变环境,且不继承
    环境变量 var   没有定义
    >(<&3 set var)			;在非管道中,括号无影响
    var=a
    >
    >echo >nul | set var=b	;设置了新环境中的var
    >set var
    var=a	;以上'set var=b'不影响上文环境
    >		;或者
    >echo >nul | (set var=b & set var)
    var=b	;设置了新环境中的var
    >set var
    var=a	;不影响上文环境
    >		;或者
    >echo c | (set /P var= & set var)
    var=c	;设置新环境中的var
    >set var
    var=a	;不影响上文环境
    
  • 或者,单行:

    >set var=a & set var & set var >&2 | echo b | (set /p var= & set var) >&2 & set var >&2
    var=a
    环境变量 var   没有定义
    var=b
    var=a
    

    在管道中使用了2号流,为保持按顺序输出,后续流也改为2#。
    其中(set /p var= & set var) >&2>&2得在括号外。

重定向Redirect

A > BC < D,是执行前的赋值操作,传递关于输入、输出之环境(广义的参数)。

  • "执行前的赋值":类似于(狭义的)传递参数,不过位置宽松,形式不同于Command Arg Arg2 ..

  • "环境":类似upvalue。

  • "输入、输出":默认是stdinstdoutstderr,传递的是变量名/地址,而非

  • 赋值顺序

    从前往后,后面的会覆盖前面的。

    可以在前面放置默认值,不影响后半部分覆盖。

    3>>%default% 1>>&3,设置流1默认为default。

    • 3作为中间/临时/中转流,初始为空。
    • 不可直接1>>%default%,否则,若default==&1,则相当于1>&1,会报错"重定向句柄 1 时,无法复制此句柄。"

流Stream

  • 来自设备、(广义)文件的数据流。描述:

    • con(console),默认输入(stdin)。

    • nul,空输出(如同不显示输出)。

    • &<number>其他编号的流。

    • <filename>文件。

  • 系统默认,使用流编号

命令使用流

findstr(、find)等命令会等待静态值参数满足后执行
"等待静态值":即,不可一边输入,一边处理。具体如:

  • 当使用管道时,不存在问题,立即执行。
  • 当使用重定向时,
    • 如果输入流是(狭义的)文件,不存在问题,立即执行;
    • 如果是输入设备(如con(console)终端),则等待输入完毕时,才会执行。
      涉及结束输入流的问题。
      • "等待输入完毕":相当于Lua中的input:read'a',会阻塞

结束输入流

命令

echo命令

不使用输入
echo 12 | echo会显示"ECHO 处于打开状态。",如同单独的echo命令(管道无作用)。

建议使用echo(+正文内容((后无空格)形式。

set命令

set /p var=,接受的输入流仅可以是单行

建议使用set /p "var=",带双引号。

call命令

形式call :<label> arg(之一)。
arg可以"%var%",使用双引号(类似set),再在子命令内使用%~1解析掉双引号。

call | Microsoft Docs

其他

Delayed Expansion

  • 运行时执行变量解析,而非加载代码块时。

  • 使用!作为变量名分隔符/标记,解析变量。
    !var!。区分于%var%

  • 需要在环境中开启。

    • 使用com /v:on/v:off
    • batch内setlocal DisableDelayedExpansionsetlocal EnableDelayedExpansion,搭配endlocal
  • 有作用范围(()parentheses)问题。

​ 参考:

其他

CMD BAT 概要windows - Command to run a .bat file - Stack Overflow

检索关键词index:cmd command batch, findstr find, stdin input, redirect pipe, read write dynamic realtime, flush refresh buffer, block wait hang, control character signal, Ctrl-D ^D, Ctrl-Z ^Z

纪念下过程,目的向导,七零八碎的拼凑起来,测试完善,但仍不够系统..

posted on 2022-05-16 23:44  萝卜L  阅读(38)  评论(0编辑  收藏  举报