Board logo

标题: [其他] cmd 命令行都有哪些黑科技? [打印本页]

作者: plp626    时间: 2016-10-4 18:44     标题: cmd 命令行都有哪些黑科技?

本帖最后由 plp626 于 2016-10-4 18:54 编辑

今天在论坛捡到俩宝贝,感觉非常实用,分享如下:

dos游戏底层新方法:

不需要choice.exe和回车就能获得按键输入的方法/黑科技


any2bat新方法:

用 certutil 实现 Hex2Bin 和 Base64 加解密


分享下我之前收集的黑科技(年代久了,你们也许觉得太平常,但第一次见到时,心里那感觉,。。。你懂的,废话少说,分享如下:

定时关机,出处不详 //当年用电脑只会点鼠标打字的我,第一次被震慑到了:
  1. :: 1小时后关机
  2. shutdown -f -s -t 3600
复制代码
chm文件反编译(把chm解包成html):// 曾经发现有个exe软件就这个功能竟然还收费,真是欺负小朋友

批处理版chm文件反编译器V1.3
  1. ::核心代码
  2. hh -decompile . test.chm
复制代码

作者: plp626    时间: 2016-10-4 18:52

  1. :: windows下复制/备份某个目录下的特定文件 // 工作中特别方便实用
  2. dir/a-d/b/s *.conf *.lst > 1.txt
  3. rar a -m0 bak.rar @1.list
复制代码

作者: codegay    时间: 2016-10-4 20:37

是编码不是加密
作者: 523066680    时间: 2016-10-4 22:55

回复 3# codegay


    这个看使用情况吧,面对一般用户,还是面对程序员
作者: CrLf    时间: 2016-10-5 01:18

最喜欢的莫过于:
  1. ren *. *.jpg
复制代码

作者: codegay    时间: 2016-10-5 04:23

bcn显然是个黑科技。
作者: CrLf    时间: 2016-10-5 14:19

回复 5# plp626


    笔误,实际上要说的是以下两个用法
  1. ren * *.jpg
  2. ren *.jpg *.
复制代码

作者: Bella    时间: 2016-10-5 16:22

本帖最后由 Bella 于 2016-10-20 02:31 编辑

回复 7# CrLf


    类似的问题, windows新建点号开头的文件
命令行下可以
  1. mkdir .foo
复制代码
桌面下必须前后都带点号
  1. .foo.
复制代码

作者: CrLf    时间: 2016-10-5 23:38

本帖最后由 CrLf 于 2016-10-5 23:40 编辑

回复 6# codegay


    那末就贴上来吧:Batch-CN——在线第三方管理,已收集1600+第三方[2016.04.24更新]
    实际上已经 1800+ 了,网页版:http://www.bathome.net/s/tool/index.html
作者: CrLf    时间: 2016-10-6 12:42

对了,不能不提 用 nslookup 获取本机外网 IP
作者: codegay    时间: 2016-10-6 13:57

回复 10# CrLf


    稳定性有点差。
  1. nslookup myip.opendns.com resolver1.opendns.com
  2. 服务器:  resolver1.opendns.com
  3. Address:  208.67.222.222
  4. DNS request timed out.
  5.     timeout was 2 seconds.
  6. *** 请求 resolver1.opendns.com 超时
复制代码

作者: plp626    时间: 2016-10-6 21:16

回复 10# CrLf


    这个有些环境不准
作者: freesoft00    时间: 2016-10-7 12:46

对了,不能不提
CrLf 发表于 2016-10-6 12:42



    加路由的环境不准确,获得的是私有地址。
另外有什么好的方法判断本机可以上网?
1、通过检测dns,这个不准确,在有路由器的环境,有时候dns是路由器地址。
2、ping一个网址,这个也不稳定,1你的环境可以ping同,其他人的网络运营商环境下也许ping不同,2有些网址禁止ping,或者有些网址被屏蔽无法ping到。
作者: /zhqsystem/zhq    时间: 2016-10-7 16:21

本帖最后由 /zhqsystem/zhq 于 2016-10-7 16:54 编辑

回复 13# freesoft00
判断上网可以用路由追踪,追踪任意一个IP当IP首字段不等于局域网地址和保留地址时就可以判定可以联网了[也有弊端,dns不通QQ能上网,网页打不开会判断无法联网]
简易代码
  1. tracert.exe -d -w 1 "microsoft.com" >nul 2>nul&&(echo,网络连接正常)||(echo,网络连接异常,无法解析)
复制代码

作者: freesoft00    时间: 2016-10-7 17:07

回复 14# /zhqsystem/zhq

谢谢!这个应该也有我说的那个第二点的情况把,我原来是通过ping微软的网址判断的,但是后来把代码给其他人用他反映代码显示无法连接网络致使后续代码无法运行,我想是它那里ping不同,所以固定的网址有这个问题。
作者: Bella    时间: 2016-10-8 01:08

本帖最后由 Bella 于 2016-10-19 19:37 编辑

回复 14# /zhqsystem/zhq

mtr


winMTR

作者: Bella    时间: 2016-10-8 01:27

回复 15# freesoft00


    ping百度就行了, 我觉得百度就是用来ping的
作者: aa77dd@163.com    时间: 2016-10-8 01:32

回复 17# Bella

举十指十趾赞成, 那就是那货最大的用处
作者: happy886rr    时间: 2016-10-10 20:56

本帖最后由 happy886rr 于 2016-10-10 20:59 编辑

生成utf8
  1. set/p=联<NUL>bom.txt
复制代码

作者: 523066680    时间: 2016-10-10 23:35     标题: 突然想起锟斤拷

本帖最后由 523066680 于 2016-10-10 23:37 编辑
  1.     [ef bb] [bf e9] [b4 a8]
  2. GBK 锘      块      川
  3.     [ef bb bf] [e9 b4 a8 ]
  4. UTF8   BOM        鴨
复制代码

作者: bailong360    时间: 2016-10-16 15:33

bat吧的Byaidu曾经发现过一个管道的特技
第一眼看到被惊艳了,感觉非常有趣,很有潜力,大概是这个样子

demo.bat 主程序
  1. @makelist|output
  2. @pause
复制代码
makelist.bat 生成数列
  1. @echo off
  2. for /l %%i in (1 1 20) do (
  3.     echo %%i
  4.     ping -n 1 localhost >nul
  5. )
复制代码
output.bat 输出
  1. @echo off
  2. :loop
  3. set n=
  4. set /p n=
  5. if not "%n%"=="" (
  6.     set /a "n=1<<n"
  7.     call echo %%n%%
  8.     goto loop
  9. ) else echo end!
复制代码
双击Demo.bat看效果
作者: pcl_test    时间: 2016-10-16 16:47

本帖最后由 pcl_test 于 2016-10-16 16:49 编辑

回复 21# bailong360

简化下代码
  1. for /l %%i in (1 1 20) do echo;%%i|(set /p n=&call set /a "1<<%%n%%"&echo;)
复制代码
跟(for /l %%i in (1 1 5) do set /p line=&call echo;%%line%%)<a.txt是类似的吧
作者: bailong360    时间: 2016-10-16 18:46

回复 22# pcl_test
原理应该是一样的,只是原以为cmd的管道是先获取了全部输出再传递给下一个程序,觉得可以动态地获取很不可思议
有进程间通信的feel
作者: CrLf    时间: 2016-10-17 01:00

本帖最后由 CrLf 于 2016-10-17 04:04 编辑

回复 23# bailong360
  1. dir /s \ | find "Desktop"
复制代码
你会发现包括 more、find 在内的很多第三方工具是“边下边播”的,而 for /f %%a in ('[COMMAND]') do xx 则是要等 [COMMAND] 执行完毕才会开始 do


贴吧原帖链接:http://tieba.baidu.com/p/4377042621

这方法其实并没有太大的实用性...它的价值其实在于引出几个很有趣的问题:
这些输出是被谁吃了?
用 set /p 为什么会跳行(改用 c 语言编译的 gets 或 getch 亦然)?
又为什么不是在延时之后立刻出现跳行现象,而一定是发生在延时的下下次 set /p?
以及 ping 之后为什么会得到奇怪的结果?
为什么会 :OUT 居然会停下来等待 :IN 的 pause?

奉上测试代码,有心人自然会意:
  1. @echo off
  2. %1 %0 :OUT | %0 :IN
  3. goto %1 :eof
  4. :OUT
  5. set /a a+=1
  6. echo %a%
  7. title %a%
  8. goto :OUT
  9. :IN
  10. setlocal enabledelayedexpansion
  11. echo -----------------
  12. set /p input=
  13. echo     1:!input!
  14. set /p input2=
  15. echo     2:!input2!
  16. set /p input3=
  17. echo     3:!input3!
  18. set /p input4=
  19. echo     4:!input4! [before sleep]
  20. for /l %%a in (1 1 1000) do (cd .)
  21. set /p input5=
  22. echo     5:!input5! [after sleep]
  23. set /p input6=
  24. echo     6:!input6!
  25. set /p input7=
  26. echo     7:!input7!
  27. set /p input8=
  28. echo     8:!input8! [before ping]
  29. ping /n 1 127.1 >nul
  30. set /p input9=
  31. echo     9:!input9! [after ping]
  32. set /p input10=
  33. echo    10:!input10!
  34. set /p input11=
  35. echo    11:!input11!
  36. set /p input10=
  37. echo    12:!input12!
  38. set /p input10=
  39. echo    13:!input13! [before pause]
  40. pause<con
  41. set /p input10=
  42. echo    14:!input14! [after pause]
  43. set /p input10=
  44. echo    15:!input15!
  45. set /p input10=
  46. echo    16:!input16!
  47. pause<con
  48. endlocal
  49. goto :IN
复制代码
通过改变变量 a 的长度并观察 title 停止刷新时的值,解方程可知管道缓冲区的 BufferSize=4095,末尾必须用于存放 \0
于是前面的现象也就得到了解答——都是缓冲区惹的祸

【以下均为推测】
假设执行了一个 命令A | 命令B,在管道内发生了如下逻辑:
命令A 执行时,向缓冲区写入文本,
当缓冲区写满 4095 字节时(含回车换行),命令A 挂起,
当缓冲区被读取时,唤醒 命令A 继续执行(唤醒的过程可能会有一个耗时),
(存疑)在命令A 唤醒时,cmd 会清理一部分缓冲区(时多时少,规律不明),
当命令A 关闭时,命令B 的 stdin 为空

也就是说,跳行的原因还是一个谜

-----------------------------------------------------------------------------------
找到两篇文章,部分佐证了这个观点:
http://blog.csdn.net/qzwujiaying/article/details/6027570
http://blog.csdn.net/guang11cheng/article/details/17144907
作者: CrLf    时间: 2016-10-17 09:34

更有意思的是用不同方式同时读取 stdin,得到的内容居然是两条时间线:
  1. #include <windows.h>
  2. #include <stdio.h>
  3. main(){
  4. int i=0,j=0;
  5. wchar_t str[8192]=L"";
  6. char temp[1111]="";
  7. for(i=0;++i;){
  8. Sleep(1000);
  9. fgetws(str,1024,stdin);
  10. wprintf(L"@1 %s\r\n",str);
  11. fgetws(str,1024,stdin);
  12. wprintf(L"@2 %s\r\n",str);
  13. system("set /p n=&call echo Batch: %n%");
  14. fgetws(str,1024,stdin);
  15. wprintf(L"@3 %s\r\n",str);
  16. fgetws(str,1024,stdin);
  17. wprintf(L"@4 %s\r\n",str);
  18. getch();
  19. }
  20. }
复制代码
结论:cmd 打破时空壁垒,穿越了
作者: aa77dd@163.com    时间: 2016-10-17 12:38

本帖最后由 aa77dd@163.com 于 2016-10-17 13:01 编辑

回复 24# CrLf

set /p 后面的
input10

从 12 到 16 是不是木有改呢

象是关于 cmd 的管道阻塞处理方式

Desktop App>Technologies System Services>Interprocess Communications>\"\"ipes

Pipe Functions

管道编程

The Windows Pipes Programming - windows“管道”编程 之 "匿名管道"


那个老版的 CMD 源码中有个 文件 cop.c,  包含了 4 个关于管道的函数 ePipe ,PipeErr, PipeWait, BreakPipes
文件 600+ 行, 我就贴上吧
cop.c
  1. #include "cmd.h"
  2. extern int LastRetCode;
  3. extern int ExtCtrlc; /* @@1 */
  4. /*  M000 ends */
  5. unsigned PipeCnt ; /* M007 - Active pipe count    */
  6. struct pipedata *PdHead = NULL; /* M007 - 1st element of pipedata list    */
  7. struct pipedata *PdTail = NULL; /* M007 - Last element of pipedata list    */
  8. unsigned PipePid ; /* M007 - Communication with ECWork    */
  9. /*** eComSep - execute a statement containing a command separator
  10. *
  11. *  Purpose:
  12. * Execute the left and right hand sides of a command separator
  13. * operator.
  14. *
  15. *  int eComSep(struct node *n)
  16. *
  17. *  Args:
  18. * n - parse tree node containing the command separator node
  19. *
  20. *  Returns:
  21. * Whatever the right hand side returns.
  22. *
  23. *  Notes:
  24. * Revised to always supply both args to Dispatch().
  25. */
  26. int eComSep(n)
  27. struct node *n ;
  28. {
  29. Dispatch(RIO_OTHER,n->lhs) ;
  30. return(Dispatch(RIO_OTHER,n->rhs)) ;
  31. }
  32. /*** eOr - execute an OR operation
  33. *
  34. *  Purpose:
  35. * Execute the left hand side of an OR operator (||).  If it succeeds,
  36. * quit.  Otherwise execute the right side of the operator.
  37. *
  38. *  int eOr(struct node *n)
  39. *
  40. *  Args:
  41. * n - parse tree node containing the OR operator node
  42. *
  43. *  Returns:
  44. * If the left hand side succeeds, return SUCCESS.  Otherwise, return
  45. * whatever the right side returns.
  46. *
  47. *  Notes:
  48. * Revised to always supply both args to Dispatch().
  49. */
  50. int eOr(n)
  51. struct node *n ;
  52. {
  53.         int i ;                         /* Retcode from L.H. side of OR   */
  54. if ((i = Dispatch(RIO_OTHER,n->lhs)) == SUCCESS)
  55.     return(SUCCESS) ;
  56. else {
  57.             LastRetCode = i;
  58.     return(Dispatch(RIO_OTHER,n->rhs)) ;
  59.         }
  60. }
  61. /*** eAnd - execute an AND operation
  62. *
  63. *  Purpose:
  64. * Execute the left hand side of an AND operator (&&).  If it fails,
  65. * quit.  Otherwise execute the right side of the operator.
  66. *
  67. *  int eAnd(struct node *n)
  68. *
  69. *  Args:
  70. * n - parse tree node containing the AND operator node
  71. *
  72. *  Returns:
  73. * If the left hand side fails, return its return code.  Otherwise, return
  74. * whatever the right side returns.
  75. *
  76. *  Notes:
  77. * Revised to always supply both args to Dispatch().
  78. */
  79. int eAnd(n)
  80. struct node *n ;
  81. {
  82. int i ; /* Retcode from L.H. side of AND   */
  83. if ((i = Dispatch(RIO_OTHER,n->lhs)) != SUCCESS)
  84. return(i) ;
  85. else
  86. return(Dispatch(RIO_OTHER,n->rhs)) ;
  87. }
  88. /********************* START OF SPECIFICATION **************************/
  89. /*        */
  90. /* SUBROUTINE NAME: ePipe        */
  91. /*        */
  92. /* DESCRIPTIVE NAME: Pipe Process        */
  93. /*        */
  94. /* FUNCTION: Execute the left side of the pipe and direct its output to*/
  95. /*      the right side of the pipe.        */
  96. /*        */
  97. /* NOTES: None        */
  98. /*        */
  99. /*        */
  100. /* ENTRY POINT: ePipe        */
  101. /*    LINKAGE: NEAR        */
  102. /*        */
  103. /* INPUT: n - parse tree node containing the pipe operator        */
  104. /*        */
  105. /* OUTPUT: None        */
  106. /*        */
  107. /* EXIT-NORMAL: The return code of the right side process.        */
  108. /*        */
  109. /* EXIT-ERROR: Failure if no pipe redirection can take place.        */
  110. /*        */
  111. /* EFFECTS:        */
  112. /*        */
  113. /*    struct pipedata {        */
  114. /*    unsigned rh ;        Pipe read handle        */
  115. /*    unsigned wh ;        Pipe write handle        */
  116. /*    unsigned shr ;        Handles where the normal...     */
  117. /*    unsigned shw ;        ...STDIN/OUT handles are saved  */
  118. /*    unsigned lPID ;        Pipe lh side PID        */
  119. /*    unsigned rPID ;        Pipe rh side PID        */
  120. /*    unsigned lstart ;        Start Information of lh side @@4*/
  121. /*    unsigned rstart ;        Start Information of rh side @@4*/
  122. /*    struct pipedata *prvpds ;   Ptr to previous pipedata struct */
  123. /*    struct pipedata *nxtpds ;   Ptr to next pipedata struct     */
  124. /*       }        */
  125. /*        */
  126. /*    unsigned PipePID;        Pipe Process ID        */
  127. /*        */
  128. /*    unsigned start_type;        Start Information        */
  129. /*        */
  130. /*        */
  131. /* INTERNAL REFERENCES:        */
  132. /* ROUTINES:        */
  133. /* PutStdErr -  Print an error message        */
  134. /* Abort    -  Terminate program with abort        */
  135. /* SetList   -  Set Link List for pipedata structure        */
  136. /* Cdup    -  Duplicate supplied handle and save the new handle*/
  137. /* Cdup2    -  Duplicate supplied handle and save the new handle*/
  138. /* Dispatch  -  Execute the program        */
  139. /* PipeErr   -  Handle pipe error        */
  140. /* Cclose    -  Close the specified handle        */
  141. /* PipeWait  -  Wait for the all pipe process completion        */
  142. /*        */
  143. /* EXTERNAL REFERENCES:        */
  144. /* ROUTINES:        */
  145. /* DOSMAKEPIPE - Make pipe        */
  146. /*        */
  147. /********************** END  OF SPECIFICATION **************************/
  148. /*** ePipe - Create a pipeline between two processes (M000)
  149. *
  150. *  Purpose:
  151. * Execute the left side of the pipe and direct its output to
  152. * the right side of the pipe.
  153. *
  154. *  int ePipe(struct node *n)
  155. *
  156. *  Args:
  157. * n - parse tree node containing the pipe operator
  158. *
  159. *  Returns:
  160. * The return code of the right side process or failure if no
  161. * pipe redirection can take place.
  162. *
  163. *  Notes:
  164. * M007 - This function has been completely rewritten for real pipes.
  165. *
  166. */
  167. int ePipe(n)
  168. struct node *n ;
  169. {
  170. struct pipedata *Pd ; /* Pipe struct pointer    */
  171. int k = 0 ; /* RH side return code    */
  172. struct node *l ; /* Copy of left side arg   */
  173. struct node *r ; /* Copy of right side arg  */
  174. extern unsigned start_type ; /* API type used to start  */
  175. TCHAR cflags ; /*    */
  176. l = n->lhs ; /* Equate locals to...    */
  177. r = n->rhs ; /* ...L & R operations    */
  178. DEBUG((OPGRP,PILVL,"PIPES:LH = %d, RH = %d ",l->type,r->type)) ;
  179. if (!(Pd = (struct pipedata *)mkstr(sizeof(struct pipedata)))) {
  180. DEBUG((OPGRP,PILVL,"PIPES:Couldn't alloc structure!")) ;
  181. return(FAILURE) ;
  182. } ;
  183. if (_pipe((int *)Pd, 0, O_BINARY)) {
  184. DEBUG((OPGRP,PILVL,"PIPES:pipe failed!")) ;
  185. PutStdErr(ERROR_NOT_ENOUGH_MEMORY, NOARGS); /* M013    */
  186. return(FAILURE) ;
  187. Abort() ;
  188. } ;
  189. SetList(Pd->rh) ; /* M009 */
  190. SetList(Pd->wh) ; /* M009 */
  191. DEBUG((OPGRP,PILVL,"PIPES:Pipe built. Handles: rd = %d wt = %d ",Pd->rh, Pd->wh)) ;
  192. DEBUG((OPGRP,PILVL,"PIPES:Pipe (pre-index) count = %d", PipeCnt)) ;
  193. if (!PipeCnt++) { /* Already some pipes?    */
  194. PdHead = PdTail = Pd ; /* No, set head/tail ptrs  */
  195. Pd->prvpds = NULL ; /* No previous structure   */
  196. DEBUG((OPGRP,PILVL,"PIPES:This is first pipe.")) ;
  197. } else {
  198. DEBUG((OPGRP,PILVL,"PIPES:This is pipe %d.", PipeCnt)) ;
  199. PdTail->nxtpds = Pd ;
  200. Pd->prvpds = PdTail ;
  201. Pd->nxtpds = NULL ;
  202. PdTail = Pd ;
  203. } ;
  204. if ((Pd->shw = Cdup(STDOUT)) == BADHANDLE) {   /* Save STDOUT (M009) */
  205. Pd->shw = BADHANDLE ; /* If err, go process it   */
  206. PipeErr() ; /* DOES NOT RETURN    */
  207. } ;
  208. DEBUG((OPGRP,PILVL,"PIPES:STDOUT dup'd to %d.", Pd->shw)) ;
  209. if (Cdup2(Pd->wh, STDOUT) == BADHANDLE) /* Make wh STDOUT (M009)   */
  210. PipeErr() ; /* DOES NOT RETURN    */
  211. Cclose(Pd->wh) ; /* Close pipe hndl (M009)  */
  212. Pd->wh = 0 ; /* And zero the holder    */
  213. if (l->type <= CMDTYP)   /* @@5a */
  214.   {   /* @@5a */
  215.     FindAndFix( (struct cmdnode *) l, &cflags ) ; /* @@5a */
  216.   }   /* @@5a */
  217. DEBUG((OPGRP,PILVL,"PIPES:Write pipe now STDOUT")) ;
  218. k = Dispatch(RIO_PIPE,l) ;
  219.         DuplicateHandle( (HANDLE)PipePid, CRTTONT(Pd->rh),
  220.                         NULL, NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
  221. if (Cdup2(Pd->shw, STDOUT) == BADHANDLE) /* M009 */
  222. PipeErr() ; /* DOES NOT RETURN    */
  223. Cclose(Pd->shw) ; /* M009 */
  224. Pd->shw = 0 ;
  225. DEBUG((OPGRP,PILVL,"PIPES:STDOUT now handle 1 again.")) ;
  226. if (k) {
  227. ExtCtrlc = 2; /* @@1 */
  228. Abort() ;
  229. }
  230. Pd->lPID = PipePid ;
  231. Pd->lstart = start_type ;  /* Save the start_type in pipedata struct */
  232. PipePid = 0 ;
  233. start_type = NONEPGM ;    /* Reset the start_type     D64      */
  234. DEBUG((OPGRP,PILVL,"PIPES:Dispatch LH side succeeded - LPID = %d.",Pd->lPID)) ;
  235. if ((Pd->shr = Cdup(STDIN)) == BADHANDLE) {    /* Save STDIN (M009) */
  236. Pd->shr = BADHANDLE ;
  237. PipeErr() ; /* DOES NOT RETURN    */
  238. } ;
  239. DEBUG((OPGRP,PILVL,"PIPES:STDIN dup'd to %d.", Pd->shr)) ;
  240. if (Cdup2(Pd->rh, STDIN) == BADHANDLE) /* Make rh STDIN (M009)    */
  241. PipeErr() ; /* DOES NOT RETURN    */
  242. Cclose(Pd->rh) ; /* Close pipe hndl (M009)  */
  243. Pd->rh = 0 ; /* And zero the holder    */
  244. if (r->type <= CMDTYP)      /* @@5a */
  245.   {      /* @@5a */
  246.     FindAndFix( (struct cmdnode *) r, &cflags) ;     /* @@5a */
  247.   } ;      /* @@5a */
  248. DEBUG((OPGRP,PILVL,"PIPES:Read pipe now STDIN")) ;
  249. k = Dispatch(RIO_PIPE,r) ;
  250. if (Cdup2(Pd->shr, STDIN) == BADHANDLE) /* M009 */
  251. PipeErr() ; /* DOES NOT RETURN    */
  252. Cclose(Pd->shr) ; /* M009 */
  253. Pd->shr = 0 ;
  254. DEBUG((OPGRP,PILVL,"PIPES:STDIN now handle 0 again.")) ;
  255. if (k) {
  256. ExtCtrlc = 2; /* @@1 */
  257. Abort() ;
  258. }
  259. Pd->rPID = PipePid ;
  260. Pd->rstart = start_type ;  /* Save the start_type in pipedata struct */
  261. PipePid = 0 ;
  262. start_type = NONEPGM ;    /* Reset the start_type  D64      */
  263. DEBUG((OPGRP,PILVL,"PIPES:Dispatch RH side succeeded - RPID = %d.",Pd->rPID)) ;
  264. if (!(--PipeCnt)) { /* Additional pipes?    */
  265. DEBUG((OPGRP,PILVL,"PIPES:Returning from top level pipe. Cnt = %d", PipeCnt)) ;
  266. return(PipeWait()) ; /* No, return CWAIT    */
  267. } ;
  268. DEBUG((OPGRP,PILVL,"PIPES:Returning from pipe. Cnt = %d", PipeCnt)) ;
  269. return(k) ; /* Else return exec ret    */
  270. }
  271. /*** PipeErr - Fixup and error out following pipe error
  272. *
  273. *  Purpose:
  274. * To provide single error out point for multiple error conditions.
  275. *
  276. *  int PipeErr()
  277. *
  278. *  Args:
  279. * None.
  280. *
  281. *  Returns:
  282. * DOES NOT RETURN TO CALLER.  Instead it causes an internal Abort().
  283. *
  284. */
  285. void PipeErr()
  286. {
  287. PutStdErr(MSG_PIPE_FAILURE, NOARGS) ; /* M013    */
  288. Abort() ;
  289. }
  290. /********************* START OF SPECIFICATION **************************/
  291. /*        */
  292. /* SUBROUTINE NAME: PipeWait        */
  293. /*        */
  294. /* DESCRIPTIVE NAME: Wait and Collect Retcode for All Pipe Completion  */
  295. /*        */
  296. /* FUNCTION: This routine calls WaitProc or WaitTermQProc for all      */
  297. /*      pipelined processes until entire pipeline is finished.    */
  298. /*      The return code of right most element is returned.        */
  299. /*        */
  300. /* NOTES:    If the pipelined process is started by DosExecPgm,        */
  301. /*      WaitProc is called.  If the pipelined process is started  */
  302. /*      by DosStartSession, WaitTermQProc is called.        */
  303. /*        */
  304. /*        */
  305. /* ENTRY POINT: PipeWait        */
  306. /*    LINKAGE: NEAR        */
  307. /*        */
  308. /* INPUT: None        */
  309. /*        */
  310. /* OUTPUT: None        */
  311. /*        */
  312. /* EXIT-NORMAL:  No error return code        */
  313. /*        */
  314. /* EXIT-ERROR: Error return code from either WaitTermQProc or WaitProc*/
  315. /*        */
  316. /*        */
  317. /* EFFECTS: None.        */
  318. /*        */
  319. /* INTERNAL REFERENCES:        */
  320. /* ROUTINES:        */
  321. /* WaitProc - wait for the termination of the specified process, */
  322. /*     its child process, and  related pipelined        */
  323. /*     processes.        */
  324. /*        */
  325. /* WaitTermQProc - wait for the termination of the specified     */
  326. /* session and related pipelined session.        */
  327. /*        */
  328. /* EXTERNAL REFERENCES:        */
  329. /* ROUTINES:        */
  330. /* WINCHANGESWITCHENTRY -  Change switch list entry        */
  331. /*        */
  332. /********************** END  OF SPECIFICATION **************************/
  333. /*** PipeWait - wait and collect retcode for all pipe completion (M007)
  334. *
  335. *  Purpose:
  336. * To do cwaits on all pipelined processes until entire pipeline
  337. * is finished.  The retcode of the rightmost element of the pipe
  338. * is returned.
  339. *
  340. *  int PipeWait()
  341. *
  342. *  Args:
  343. * None.
  344. *
  345. *  Returns:
  346. * Retcode of rightmost pipe process.
  347. *
  348. */
  349. PipeWait()
  350. {
  351. unsigned i ;
  352. DEBUG((OPGRP,PILVL,"PIPEWAIT:Entered - PipeCnt = %d", PipeCnt)) ;
  353. while (PdHead) {
  354. if (PdHead->lPID) {
  355.      DEBUG((OPGRP, PILVL, "PIPEWAIT: lPID %d, lstart %d", PdHead->lPID, PdHead->lstart));
  356.      if ( PdHead->lstart == EXECPGM )
  357.        {
  358. i = WaitProc(PdHead->lPID) ; /* M012 - Wait LH   */
  359. DEBUG((OPGRP,PILVL,"PIPEWAIT:CWAIT on LH - Ret = %d, SPID = %d", i, PdHead->lPID)) ;
  360.        }
  361. //      else
  362. //        {
  363. // WaitTermQProc(PdHead->lPID, &i) ;
  364. //
  365. // DEBUG((OPGRP,PILVL,"PIPEWAIT:Read TermQ on LH - Ret = %d, PID = %d", i, PdHead->lPID)) ;
  366. //        } ;
  367. //
  368. } ;
  369. if (PdHead->rPID) {
  370.      DEBUG((OPGRP, PILVL, "PIPEWAIT: rPID %d, rstart %d", PdHead->rPID, PdHead->rstart));
  371.      if ( PdHead->rstart == EXECPGM )
  372.        {
  373. i = WaitProc(PdHead->rPID) ; /* M012 - Wait RH   */
  374. DEBUG((OPGRP,PILVL,"PIPEWAIT:CWAIT on RH - Ret = %d, PID = %d", i, PdHead->rPID)) ;
  375.        }
  376. //      else
  377. //        {
  378. // WaitTermQProc(PdHead->rPID, &i) ;
  379. //
  380. // DEBUG((OPGRP,PILVL,"PIPEWAIT:Read TermQ on LH - Ret = %d, PID = %d", i, PdHead->rPID)) ;
  381. //        } ;
  382. } ;
  383. PdHead = PdHead->nxtpds ;
  384. } ;
  385. DEBUG((OPGRP,PILVL,"PIPEWAIT: complete, Retcode = %d", i)) ;
  386. PdTail = NULL ; /* Cancel linked list...    */
  387. PipeCnt = PipePid = 0 ; /* ...pipe count and pipe PID    */
  388.         LastRetCode = i;
  389. return(i) ;
  390. }
  391. /*** BreakPipes - disconnect all active pipes  (M000)
  392. *
  393. *  Purpose:
  394. * To remove the temporary pipe files and invalidate the pipedata
  395. * structure when pipes are to be terminated, either through the
  396. * completion of the pipe operation or SigTerm.
  397. *
  398. * This routine is called directly by the signal handler and must
  399. * not generate any additional error conditions.
  400. *
  401. *  void BreakPipes()
  402. *
  403. *  Args:
  404. * None.
  405. *
  406. *  Returns:
  407. * Nothing.
  408. *
  409. *  Notes:
  410. * M007 - This function has been completely rewritten for real pipes.
  411. *
  412. * *** W A R N I N G ! ***
  413. * THIS ROUTINE IS CALLED AS A PART OF SIGNAL/ABORT RECOVERY AND
  414. * THEREFORE MUST NOT BE ABLE TO TRIGGER ANOTHER ABORT CONDITION.
  415. *
  416. */
  417. void BreakPipes()
  418. {
  419. unsigned i ;
  420. struct pipedata *pnode;
  421. DEBUG((OPGRP,PILVL,"BRKPIPES:Entered - PipeCnt = %d", PipeCnt)) ;
  422. /* The following two lines have been commented out */
  423. /* because the NULL test on PdTail should be enough, */
  424. /* and more importantly, even if PipeCnt is 0, you */
  425. /* may still have been servicing a pipe in Pipewait */
  426. /* if (!PipeCnt)        */ /* If no active pipes...   */
  427. /* return ;       */ /* ...don't do anything    */
  428. pnode = PdTail;
  429. /* First, kill all of the processes */
  430. while (pnode) {
  431. if (pnode->lPID) {
  432. /* M012 */ i = KillProc(pnode->lPID, FALSE) ; /* Kill LH   */
  433. DEBUG((OPGRP,PILVL,"BRKPIPES:LH (Pid %d) killed - Retcode = %d", PdTail->lPID, i)) ;
  434. } ;
  435. if (pnode->rPID) {
  436. /* M012 */ i = KillProc(pnode->rPID, FALSE) ; /* Kill RH   */
  437. DEBUG((OPGRP,PILVL,"BRKPIPES:RH (Pid %d) killed - Retcode = %d", PdTail->rPID, i)) ;
  438. } ;
  439. pnode = pnode->prvpds ;
  440. }
  441. /* Wait for the processes to die, and clean up file handles */
  442. while (PdTail) {
  443. if (PdTail->lPID) {
  444.    if (PdTail->lstart == EXECPGM) {
  445.       i = WaitProc(PdTail->lPID);
  446. //    } else {
  447. //       WaitTermQProc(PdTail->lPID, &i) ;
  448.    }
  449. } ;
  450. if (PdTail->rPID) {
  451.    if (PdTail->rstart == EXECPGM) {
  452.       i = WaitProc(PdTail->rPID);
  453. //    } else {
  454. //       WaitTermQProc(PdTail->rPID, &i) ;
  455.    }
  456. } ;
  457. if (PdTail->rh) {
  458. Cclose(PdTail->rh) ; /* M009 */
  459. DEBUG((OPGRP,PILVL,"BRKPIPES:Pipe read handle closed")) ;
  460. } ;
  461. if (PdTail->wh) {
  462. Cclose(PdTail->wh) ; /* M009 */
  463. DEBUG((OPGRP,PILVL,"BRKPIPES:Pipe write handle closed")) ;
  464. } ;
  465. if(PdTail->shr) {
  466. FlushFileBuffers(CRTTONT(PdTail->shr));
  467. Cdup2(PdTail->shr, STDIN) ; /* M009 */
  468. Cclose(PdTail->shr) ; /* M009 */
  469. DEBUG((OPGRP,PILVL,"BRKPIPES:STDIN restored.")) ;
  470. } ;
  471. if(PdTail->shw) {
  472. Cdup2(PdTail->shw, STDOUT) ; /* M009 */
  473. Cclose(PdTail->shw) ; /* M009 */
  474. DEBUG((OPGRP,PILVL,"BRKPIPES:STDOUT restored.")) ;
  475. } ;
  476. PdTail = PdTail->prvpds ;
  477. } ;
  478. PdHead = NULL ; /* Cancel linked list...    */
  479. PipeCnt = PipePid = 0 ; /* ...pipe count and pipe PID    */
  480. DEBUG((OPGRP,PILVL,"BRKPIPES:Action complete, returning")) ;
  481. }
  482. /*** eParen - execute a parenthesized statement group
  483. *
  484. *  Purpose:
  485. * Execute the group of statements enclosed by a statement grouping
  486. * operator; parenthesis().
  487. *
  488. *  int eParen(struct node *n)
  489. *
  490. *  Args:
  491. * n - parse tree node containing the PAREN operator node
  492. *
  493. *  Returns:
  494. * Whatever the statement group returns.
  495. *
  496. *  Notes:
  497. * M000 - Altered to always supply both args to Dispatch().
  498. * M004 - Debug statements were added for SILTYP operator.
  499. * **  WARNING  **
  500. * BOTH THE LEFT PAREN AND THE SILENT OPERATOR (@) USE eParen
  501. * WHEN DISPATCHED.  CHANGING ONE WILL AFFECT THE OTHER !!
  502. */
  503. int eParen(n)
  504. struct node *n ;
  505. {
  506. #ifndef NODEB
  507. if (n->type == PARTYP)
  508.                 DEBUG((OPGRP,PNLVL,"ePAREN: Operator is Paren")) ;
  509. else if (n->type == SILTYP)
  510.                 DEBUG((OPGRP,PNLVL,"ePAREN: Operator is Silent")) ;
  511. #endif
  512. return(Dispatch(RIO_OTHER,n->lhs)) ;
  513. }
复制代码
我还是去浇花来得轻松
https://play.google.com/store/ap ... m.tedrasoft.plumber
作者: Bella    时间: 2016-10-17 15:03

本帖最后由 Bella 于 2016-10-17 15:19 编辑

回复 24# CrLf
  1. @echo off
  2. fsutil file createnew 4176B 4176 >nul
  3. echo 4176B
  4. type 4176B | cd >nul
  5. pause
  6. echo;
  7. fsutil file createnew 4177B 4177 >nul
  8. echo 4177B
  9. type 4177B | cd >nul
  10. pause
复制代码

作者: CrLf    时间: 2016-10-17 15:37

回复 27# Bella


    这是为什么呢?
作者: aa77dd@163.com    时间: 2016-10-17 16:25

回复 28# CrLf


    4176 = 4096 + 80
作者: Bella    时间: 2016-10-18 02:15

本帖最后由 Bella 于 2016-10-20 02:30 编辑

回复 28# CrLf


fsutil file createnew 这命令不错, 测试的时候有用
作者: Bella    时间: 2016-10-18 02:15

回复 26# aa77dd@163.com


    我以为用树莓派浇花
作者: aa77dd@163.com    时间: 2016-10-18 02:37

本帖最后由 aa77dd@163.com 于 2016-10-18 02:43 编辑

回复 31# Bella

看了下别人的方案,   传感器,  水泵开关这些需要一些硬件接口资料, 事实上这简单的方案,

纯粹用电子电路也差不多可以实现了
纯电子电路的最简陋方案: 湿度传感器 湿度低于 干燥阀值 , 启动水泵;  湿度高于湿润阀值, 关闭水泵. 简单原理如此, 但实现上肯定会有很多细节问题要解决

我倒是想过做成个打印机, 也不是很好玩, 一直没入手




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2