标题: [求助]重定向操作符是否可以复制stdin至句柄1-9
[打印本页]
作者: everest79
时间: 2007-1-18 07:23
标题: [求助]重定向操作符是否可以复制stdin至句柄1-9
设想,能不能完成以下工作?
pause 3<&0
set p=<&3
或
pause 2>file 3<&0
作者: hxuan999
时间: 2007-1-19 10:26
想不通,期待ing...
作者: electronixtar
时间: 2007-1-19 22:44
其实我也不知道,用Willsort的一句话,句柄这个东西近乎于CMD的bug,完全抄袭LinuxShell
作者: everest79
时间: 2007-1-19 22:54
这下可好,本来想通过这个来获取输入的
作者: electronixtar
时间: 2007-1-19 22:57
其实CMD里有很多东西等待发现呢,Everest79兄可以自己研究下
作者: everest79
时间: 2007-1-19 23:11
叫我弟弟,我正年轻类,叫老了
我外语差的要命,原来还有个小白帮忙去翻一些国外的技术文档之类的现在都没有啦
这个问题我已经研究了快三个月了,隔几天无聊时总会拿出来试,一直木没结果
有时咬牙想再去学C,又想起概念还停在用debug修改游戏时代
句柄最大的难题是根本没办去复制输入,我在网上看到过有重定向至con来释放句柄的,我怀疑是不是这个还有隐藏开关之类的
作者: electronixtar
时间: 2007-1-19 23:23
叫人把cmd.exe静反了慢慢看。听说上次泄漏那个Win2k的源代码里也有cmd.exe啊?谁有传一份上来?呵呵
作者: everest79
时间: 2007-1-20 08:26
介个要求过高啦,俺摆不平
作者: willsort
时间: 2007-1-20 10:22
Re everest79:
其实至今为止,我对CMD句柄的复制与重定向仍然有些懵懂。electronixtar兄所提到的漏洞一说,大约出自于下面的主题[1]。因为其中言语仅仅是推测之辞,望兄自加甄别,去伪存真。
对于句柄复制,我所见到的提及最多的文档就是Windows自己的帮助与支持中“使用命令重定向操作符”一节,可见Windows用户对微软的这一从*inx平台移植的特性并没有付诸更多的关心。
实际应用中,我绝少应用句柄复制的特性。因为这个特性似乎总可以通过其它更简单的方法来实现。
set /p var=input: 3<defined.txt 0<&3
这一语句似乎可以实现兄在主楼所提到的第一个疑问。
3<define.txt 将defined.txt的字符流指向句柄3,然后0<&3将句柄0的输入读取特性复制到句柄3(也可以理解为将句柄3指向了句柄0),所以set /p的输入读取是间接通过句柄3指向了defined.txt文件。但是,我们为什么不应用 set /p var=input: <defined.txt 形式直接通过句柄0从defined.txt中获取输入呢?
从另一方面来讨论:假设程序test使用句柄3作输入读取,此时我们可以使用 test <input.txt 3<&0 的形式从input.txt获取输入;同时我们也可以用 test 3<input.txt 的方式从input.txt获取输入。
当然,句柄复制仍然有一些奇怪的特性,值得我们去深入研究它的应用。
例如,在cmd下执行下面的命令行:
cmd
echo echo %var%>test.bat
set /p var=in: 0<&3 3<test.bat
此时,我们会发现set /p仍然从句柄0的原始指向——控制台(CON)获取输入,而没有从test.bat中获取,但是当我们输入val的值后回车时,发现test.bat的输入通过句柄3,再通过句柄0到达了第一句cmd所嵌套的命令解释外壳的输入接口,从而执行了test.bat中的语句,显示刚刚定义的变量var,再之后cmd这层内嵌壳被强制脱掉,回到原始cmd外壳,变量var被丢弃了。
[1][已结]批处理语句中的 2>nul 1>nul 是什么意思
http://www.cn-dos.net/forum/viewthread.php?tid=16942#pid115971
[
Last edited by willsort on 2007-1-20 at 10:43 AM ]
作者: everest79
时间: 2007-1-20 13:07
谢谢willsort的回答,是我理解错误
第一,我将自定义句柄3-9理解为七个可以存储字符的内存空间(抽象),看到你的例子才发现自定义句柄是这样的
rem 定义句柄4输入
4<file.txt
rem 定义句柄4输出
4>file.txt
应当是自定义句柄在使用之前首先应指定设备
第二,看了以上例子才知道句柄的复制与转向是两个相附又相反的概念,例如输入复制及输入转向"<&",拥有输入功能的句柄只有一个就是0
4<file.txt 0<&4
首先定义句柄4,因为是输入所以一定为4<file.txt
1.复制概念是将0的属性复制到4,句柄4拥有了0的输入读取功能
2.而转向概念为4指向0,句柄0以输入读取方式来获得自定义的句柄4
以上两者其实都是句柄4定义的设备代替了键盘输入
第三,那么逻辑得到输出复制及输出转向的概念(这个我们常用)
4>file.txt 1>&4
4>file.txt 2>&4
同样复制概念4拥有了1的输出特性,但4定义了新设备为file.txt,也就代替了正常屏幕输出消息,其实这个更像windows的剪贴功能而非复制,若是复制那么1也应同样有着屏幕输出的功能,为什么会不显示
而转向概念就可以很好的解释这个逻辑故障,因为4所定义的设备file.txt取代了1原有的设备msg print,所以转向概念的延伸大概就是"4>file.txt 1>&4"="1>file.txt"
第四,这里不得不提一下句柄3的特性
:sub1
echo d 1>nul 3>nul
::随意执行命令
echo d 1>con 4>con
::恢复正常
:sub2
find "." d 2>nul 3>nul
::随意执行命令
find "." d 2>con 5>con
这样会发现执行sub1如同每句后边执行了1>nul
而sub2有如每句后边都执行了2>nul
而释放命令为 X>con X+3>con
我可以找到的解释是同时转向中有句柄3,句柄3会挂起一同转向的句柄X,并将其属性赋于3+X,而且指定新设备为nul,同时句柄3生成的新句柄是持久性的,除非同时手工释放X与3+X
句柄3在批处理中的应用
@echo off 2>nul 3>log.txt
find "." dd
as
echo a
echo b 1<&2
pause
在当前窗口没有关闭的情况下,log.txt只读访问
第五,就是我的假设了,不能成立,无法将stdin的输入转向或复制到某个自定义句柄或设备中
作者: everest79
时间: 2007-1-20 13:16
Quote: |
Originally posted by rubik at 2007-1-19 11:12 PM:
windows 目录中有个微软自带的批处理,只有一句话:
If Not Exist %1 Copy Nul: %1 > Nul: 2>&1 |
|
这个是创建空文件的吧?
作者: qzwqzw
时间: 2007-1-21 04:06
将以上的概念化作C语言的概念,并用类C语法来描述
设备就是具有字符I/O指针的结构体,可以将它看成一个文件
typedef struct { *char io_ptr; } FILE;
标准设备就是已经已经定义好的文件
FILE stdin, stdout, stderr;
句柄作为设备的指向就是一个文件指针
FILE *handle;
所有的句柄构成一个指针数组,0,1,2分别被初始化为stdin,stdout,stderr的地址
FILE *handle[10]={&stdin, &stdout, &stderr};
---------------------------------------------------------------------
重定向可以看作文件指针的重新赋值
3<defined.txt 相当于 handle[3]=&defined.txt;
2>nul 相当于 handles[2]=&nul;
同样,句柄的复制也可以看作指针的赋值
0<&3 相当于 handle[0]=handle[3];
---------------------------------------------------------------------
从此就可以看出楼上的例子中为什么一定要先 3<defined.txt 再 0<&3
因为 3<defined.txt 之后 handle[3] 才会有地址
也才可以在通过 0<&3 把 defined.txt 的地址传给 handle[0]
handle[3]=&defined.txt;
handle[0]=handle[3];
这当然等价于
handle[0]=&defined.txt;
也就是说 3<defined.txt 0<&3 等价于 0<defined.txt
---------------------------------------------------------------------
另外关于句柄3特性的问题
如果你认真研读过9楼给出的链接
就会发现所谓X+3的说法并不确切
这与你的测试比较局部有关
其中真正的原因仍在于句柄备份
作者: tao0610
时间: 2007-1-21 05:11
句柄其实可以被看作系统规范好的指针的指针.
可以用函数GlobalLock()锁定内存中的对象
&0,&1,&2就像qzwqzw说得可以看成文件形式
而自定义的&3-&9更像一个索引.
&3-&9句柄只有当唯一的确定了一个项目的时候,它才开始有意义.
应用结束后会解除那块的内存锁定.恢复原来的状态.
所以句柄重定向只能应用于当前的那行命令.并有先后顺序.
11楼所说的句柄3生成的新句柄是持久性的,需要手工释放应该不太准确.
作者: everest79
时间: 2007-1-21 13:05
3+x是有点想当然了,昨晚看得头晕,把&3的属性与&3复制的属性搞在一起了,又一个概念错误,难道我真的老了?
今天看了又再测试了一下,发现以下特征
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 2>con 4>con ;er=&2 ;co=&5
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 4>nul 1>&4 ;er=&4 ;co=&5
d 2>con 4>con ;er=&2 ;co=&5
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 4>nul ;er=&4 ;co=&5
d 5>nul ;er=&4 ;co=&5
d 2>con 4>con ;er=&2 ;co=&5
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 4>nul ;er=&4 ;co=&5
d 5>nul ;er=&4 ;co=&5
d 2>nul 4>nul ;er=&5 ;co=&6
d 2>con 5>con ;er=&2 ;co=&6
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 4>nul ;er=&4 ;co=&5
d 2>nul 4>nul ;er=&5 ;co=&6
d 2>nul 5>nul ;er=&6 ;co=&7
d 2>con 6>con ;er=&2 ;co=&7
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 2>nul 3>nul ;er=&4 ;co=&5
d 2>nul 3>nul ;er=&4 ;co=&5
d 2>con 4>con ;er=&2 ;co=&5
cmd ;er=&2 ;co=&3
d 2>nul 3>nul ;er=&4 ;co=&5
d 2>nul 4>nul ;er=&5 ;co=&6
d 2>nul 4>nul ;er=&5 ;co=&6
d 2>nul 4>nul ;er=&5 ;co=&6
d 2>con 5>con ;er=&2 ;co=&6
cmd ;ou=&1 ;co=&3
d 1>nul 3>nul ;ou=&4 ;co=&5
d 1>nul 4>nul ;ou=&5 ;co=&6
d 1>nul 5>nul ;ou=&6 ;co=&7
d 1>nul 6>nul ;ou=&7 ;co=&8
d 1>nul 7>nul ;ou=&8 ;co=&9
d 1>nul 8>nul ;ou=&9 ;co=&?
d 1>nul 9>nul ;ou=&? ;co=&?
cmd ;ou=&1 ;co=&3
d 1>nul 3>nul ;ou=&4 ;co=&5
d 1>con 4>con ;ou=&1 ;co=&5
d 1>nul 5>nul ;ou=&6 ;co=&7
d 1>con 6>con ;ou=&1 ;co=&7
d 1>nul 7>nul ;ou=&8 ;co=&9
昨天我的确没认真去看那个贴子
至于&3生成的新句柄是持久的这一点,也不是一定的,前提是&3生成的第一个新句柄,中间没有再使用句柄4,在释放前或窗体结束前是持久的
作者: lxmxn
时间: 2007-1-21 14:06
你们高手之间的讨论,偶就插不上嘴啦,哇咔咔~~你们继续,我看着你们精彩的讨论呢,嘻嘻~
作者: electronixtar
时间: 2007-2-11 04:44
瞻仰~~~
作者: jianyaogao
时间: 2007-3-17 20:42
learning, keep up
作者: picat
时间: 2007-9-18 21:03
好复杂,留个脚印,日后消化~~