windows输入重定向中#句柄备份#原理

重定向是指使用重定向符号对输入或输出位置进行重新指定。

以下是理论说明,懂的可以跳过,也可以先看例子,遇到不明白的再倒回来看。

重定向符号有< 、> 、>> 、<& 、>& 和| 共六个。

 

重定向符号的作用如下表所示:

 

符号      作用

——————————————————————————————

<      从文件或设备(如默认的con 键盘)中读取命令输入。

>      将命令输出写入到文件或设备(如prn 打印机)中。 

>>     将命令输出添加到文件末尾而不删除文件中的信息。

<&    从后一个句柄读取输入并写入到前一个句柄输出中。

>&    将前一个句柄的输出写成后一个句柄的输入。

|      读取前一个命令中的输出作为后一个命令的输入。也称作管道符。

——————————————————————————————

注意:句柄的输入输出只是其指向,真正的输入输出是靠设备。

重定向符号的默认句柄,< 的默认句柄是0,> 的默认句柄是1。

 

可用句柄(0 - 9)如下表:

 

句柄        句柄号      说明

——————————————————————————————

STDIN        0        标准输入,默认从键盘输入

STDOUT      1       标准输出,默认输出到命令提示符窗口

STDERR      2          标准错误输出,默认输出到命令提示符窗口

UNDEFINED  3-9       这些句柄由应用程序和各个具体工具单独定义。

——————————————————————————————

STD 即Standard —— 标准的缩写。

 

设备

标准输入设备为键盘,用con 表示。

标准输出设备为控制台(即命令提示符),默认也用con 表示。

常用的还有:

空设备,用nul 表示。

存储设备,文件就归到这类。

不常用的如:打印机prn。

 

指向

句柄实际上也是一组0 1 数据,是存储了一个指向。

句柄0 默认指向con,这里con 为标准输入设备,即键盘。

句柄1 默认指向con,这里con 为标准输出设备,即控制台。

句柄2 默认也指向con,同1。

此外,我们对句柄的指向重新设定(即所谓的重定向)时,可以改变句柄的指向。

如1>nul 是让“标准输出”数据输出到空设备,效果就是屏蔽输出。

特别之处: 3 - 9 默认是没有指向的,我们可以用(空)来表示,注意是不同于空设备nul 的哦!

 

 

下面拿个简单的例子来说明

pause>nul

后面的>nul 的作用就是屏蔽了pause 命令的默认输出“请按任意键继续. . .”。

以上是简单的描述,而实际的过程可没那么简单:

首先确定重定向符号为>;

接着检查句柄号,发现没有,控制台为其加上默认句柄1,此时变成pause 1>nul;

由于句柄1的默认指向con,此时要被临时设定为指向nul,为了之后取回原来的指向,所以要先对1 的指向进行备份,备份到句柄3,备份过后临时设定1 指向nul;

(为什么要备份,为什么要备份到3 而不是4?见下文)

到这时这条语句才被执行,效果就是批处理暂停,没有输出只有一个光标闪阿闪。

执行完后1要取回原来的指向,1 的指向在上面被备份到3,不管3 的指向有没有改变1 要取回它的指向来,取回后1 指向con;3 的指向被取走,由于3 没有备份,所以恢复到原来的(空),即无指向。

至此整个过程描述完毕。

可以发现这时的情况与最初是相同的,所有句柄的指向都是其默认值。

 

    接着引出 句柄(指向)备份理论。

 

1.  当指向为非空的句柄被重新设置时要进行备份,而且是备份到第一个没有指向的句柄。

2.  语句运行完后要取回其备份,而不管备份中的句柄指向有没有改变。

3.  如果当前状态下3 - 9 这七个句柄都有了指向,这时新设置的句柄其原指向将不再备份。

复制代码

1.  另一种表述:也就是说当指向为(空)的句柄被设定时是不需要备份的。如:复制句柄时源句柄不备份,因为没有被再次设置。

2.  补充说明:一个句柄只能存储一个指向。

  

还有一个特别的例子:

echo 你好!>nul >hello.txt >prn >con

它使用的是相同的句柄1,这时要以最后一个为准,其他的忽略。把它存为批处理运行,能够清楚的看到前面的三种指向直接被剪掉了。

同理:

echo 你好!1<&3 >nul

也以后面的”>nul“ 为准,即不显示”你好!“。

 

具体例子讲解

1.  @echo off

2.  echo 哇,这就是传说中的树叶吗?>con 3>nul

3.  echo 我有一片神奇的树叶(吹口哨),

4.  echo 你看不见我,

5.  echo 我现身,>con

6.  echo 我又隐身啦。

7.  echo 谁偷了我的叶子,快还我。>con 4>con

8.  echo 没穿裤裤被你们看到了!

9.  pause>nul

复制代码

哇,这就是传说中的树叶吗?

这句用了“>con >nul” 同示例三,首先 句柄1 指向要被设为con,先备份到3 再设定;第二步 这时3 指向为con,现在又要设为nul,先备份con 到4;最后1 指向con,3 指向nul,4 指向con;所以这句执行时是要显示的。

执行完后返回,1 取回3的指向nul,3 取回4 的指向con,4 恢复(空),所以返回结束时1 指向nul,3 指向con。假设这时状态为A。

因此接下来两句“我有一片神奇的树叶(吹口哨),”,“你看不见我,” 是不显示的。

“我现身,” 这句设定为“>con”。执行时1 为con,原来的nul 备份到4(因为前面3 已经为con 不是没有指向了);执行完后1 取回备份nul,4 恢复(空)。这时的状态还是A。

所以下一句“我又隐身啦。” 还是不显示。

倒数第二句“谁偷了我的叶子,快还我。”

设定为“>con 4>con”,首先 句柄1 指向要被设为con,3 已经不为(空)了,所以备份nul 到4;第二步 这时4 指向为nul,现在又要设为con,先备份nul 到5;最后1 指向con(3 指向nul)4 指向con,5 指向nul;所以这句显示。

返回时1取回4 的指向con,4 取回5 的指向nul,5 恢复(空)。而这时状态已经不同于A 了,设为状态B。最后一句“没穿裤裤被你们看到了!” 使用的是状态B 的句柄指向,所以也显示。

  

补充

我们可以比较一下下面两句的差别

echo 你好!>con 2>con

echo 你好!

(有人会问了“你不是说句柄1 和2 默认指向为con 吗?”)

没错,我来解释一下。

第一句对句柄1和2 进行了重新设定(虽然是和默认一样的),因此要有备份和取回的过程;

而第二句没有设定,直接取默认值作为当前设定(不需要备份什么的哦);

这样第二句就比第一句快一点,如果在一个循环多次的程序中使用,速度差别就很明显了。

 

应用

一次性屏蔽错误输出(加在开始屏蔽的语句后面)

2>nul 3>nul

 

一次性将输出写入文件a.txt(不包括错误反馈,用法同上)

>&3 3>a.txt

 

问题:经过重定向后句柄的指向已经不同于默认指向了,还能恢复成原来的默认指向吗?

回答:因为指向不能设定或复制成空,所以语句运行完后的指向如果改变了是不能回到默认指向的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重定向系统各临文件夹到另外盘符 首先要在“开始”——“运行”内输入“regedit”打开注册表编辑器,然后要在“文件”下拉菜单的“导出”功能备份好注册表,以防万一,接着在左侧窗口依次打开: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders 在右侧窗口里,你看到的“名称”就代表那些特殊的文件夹,“数据”就是它们所对应的默认存储路径。修改默认的路径就可以让你的桌面文件夹移动了,下面是所有的. 下面介绍一下各个“名称”所代表的文件夹 名称 含义 默认路径 AppData 应用程序数据目录 C:\Documents and Settings\User name\Application Data Cookies Cookies路径 C:\Documents and Settings\User name\Cookies Desktop 桌面路径 C:\Documents and Settings\User name\桌面 Favorites 收藏夹 C:\Documents and Settings\User name\Favorites NetHood NetHood路径 C:\Documents and Settings\User name\NetHood Personal 我的文档 C:\Documents and Settings\User name\My Documents PrintHood 打印 C:\Documents and Settings\User name\PrintHood Recent 文档项路径 C:\Documents and Settings\User name\Recent SendTo SendTo路径 C:\Documents and Settings\User name\SendTo Start Menu 开始菜单路径 C:\Documents and Settings\User name\「开始」菜单 Templates 新建文件目录 C:\Documents and Settings\User name\Templates Programs 程序菜单路径 C:\Documents and Settings\User name\「开始」菜单\程序 Startup 启动路径 C:\Documents and Settings\User name\「开始」菜单\程序\启动 History 网页历史记录 C:\Documents and Settings\ User name \Local Settings\History My Pictures 图片收藏 C:\Documents and Settings\User name\My Documents\My Pictures My Music 我的音乐 C:\Documents and Settings\User name\My Documents\My Music My Video 我的视频 C:\Documents and Settings\User name\My Documents\My Videos Cache Internet临文件夹 C:\ Documents and Settings\User name \Temporary Internet Files 这些文件夹称为Shell文件夹 其“User name”为当前用户的名称 了解了对应的文件夹,就可以根据自己的需要去更改对应的路径了。(千万不要在这儿改啊,那样可就瞎忙乎了,系统重起后它会恢复成原来的路径) 在同一层你可以看到一个“User Shell Folders”的子键,即在HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ User Shell Folders 这里包括了用户定制的所有Shell文件夹的值项。只要通过修改“数据”,就可以改变它们的存储路径。双击需要修改的名称,在弹出的“编辑字符串”的“数值数据”里填上你要更改的完整路径,按下“确定”就完成了。如果没有你需要的,可以在右边窗口单击鼠标右键,选择“新建”菜单的“字符串值”命令,对应上表,添加一个用于Shell文件夹的字符串值。 在上面的文件夹,并没有outlook的通讯簿和邮件存放路径,它们分别在 通讯簿路径: HKEY_CURRENT_USER\Software\Microsoft\WAB\WAB4\Wab File Name主键下,将
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值