草庐IT

windows - 如何从命令提示符*不带换行符*发送 EOF?

coder 2023-11-12 原文

当然,要从命令提示符发送 EOF,Enter 后跟 Ctrl-Z 就可以了。

C:\> type con > file.txt
line1
line2
^Z

这有效,file.txt 包含 line1\r\nline2\r\n。但是如果没有最后一个换行符,你怎么能做同样的事情,以便 file.txt 包含 line1\r\nline2

在 Linux 中,解决方案是按 Ctrl-D 两次1。但是 Windows 上的等价物是什么?命令提示符将愉快地在行尾打印 ^Z 而不发送 EOF。 (如果您按下 Enter,那么您键入的任何 ^Z 都会作为文字转义字符写入文件!)

如果在 Windows 上无法执行此操作,那是为什么?


1 https://askubuntu.com/questions/118548/how-do-i-end-standard-input-without-a-newline-character

最佳答案

命令 type con > file.txt 在 cmd shell 中对 ^Z 没有任何特殊处理,因为目标文件不是 contype 命令未在 Unicode (UTF-16LE) 输出模式下运行。在这种情况下,唯一的 ^Z 处理在 ReadFile 中。调用自身,对于控制台输入缓冲区,如果一行以 ^Z 开头,它有一个未记录的行为返回读取的 0 字节。

让我们用附加的调试器检查一下,注意读取的字节数 (lpNumberOfBytesRead) 是第 4 个参数(x64 中的寄存器 r9),它作为输出参数通过引用返回。

C:\Temp>type con > file.txt
Breakpoint 1 hit
KERNELBASE!ReadFile:
00007ffc`fb573cc0 48895c2410      mov     qword ptr [rsp+10h],rbx
                                          ss:00000068`c5d1dfa8=000001e3000001e7
0:000> r r9
r9=00000068c5d1dfd0

0:000> pt
line1
KERNELBASE!ReadFile+0xa9:
00007ffc`fb573d69 c3              ret

0:000> dd 68c5d1dfd0 l1
00000068`c5d1dfd0  00000007

正如您在上面看到的,读取 "line1\r\n" 是 7 个字符,正如预期的那样。接下来让我们输入 "\x1aline2\r\n" 并查看据报道 ReadFile 读取了多少字节:

0:000> g
Breakpoint 1 hit
KERNELBASE!ReadFile:
00007ffc`fb573cc0 48895c2410      mov     qword ptr [rsp+10h],rbx
                                          ss:00000068`c5d1dfa8=0000000000000000
0:000> r r9
r9=00000068c5d1dfd0

0:000> pt
^Zline2
KERNELBASE!ReadFile+0xa9:
00007ffc`fb573d69 c3              ret

0:000> dd 68c5d1dfd0 l1
00000068`c5d1dfd0  00000000

正如你在上面看到的,这次它读取了 0 个字节,即 EOF。在 ^Z 之后键入的所有内容都将被忽略。

但是,您想要的是在输入缓冲区中出现 ^Z 的任何地方获得此行为。 type 会为您执行此操作,但前提是它以 Unicode 模式执行,即 cmd/u/c type con > file.txt。在这种情况下,cmd 确实有特殊处理来扫描 ^Z 的输入。但我敢打赌您不想要 UTF-16LE 文件,尤其是因为 cmd 不会编写 BOM 以允许编辑器检测 UTF 编码。

您很幸运,因为碰巧 copy con file.txt 完全符合您的要求。它在内部调用 cmd!ZScanA 扫描每一行以查找 ^Z 字符。我们可以在调试器中看到这一点,但这次我们处于完全未记录的领域。经过检查,该函数的第三个参数(x64 中的寄存器 r8)似乎是作为输入输出参数读取的字节数。

让我们重新开始,输入 7 个字符的字符串 "line1\r\n":

C:\Temp>copy con file.txt
line1
Breakpoint 0 hit
cmd!ZScanA:
00007ff7`cf4c26d0 48895c2408      mov     qword ptr [rsp+8],rbx
                                          ss:00000068`c5d1e9d0=0000000000000000
0:000> r r8; dd @r8 l1
r8=00000068c5d1ea64
00000068`c5d1ea64  00000007

在输出时,扫描的长度仍然是 7 个字符:

0:000> pt
cmd!ZScanA+0x4f:
00007ff7`cf4c271f c3              ret
0:000> dd 68c5d1ea64 l1
00000068`c5d1ea64  00000007
0:000> g

接下来输入23(0x17)个字符串"line2\x1a Ignore this...\r\n":

line2^Z Ignore this...
Breakpoint 0 hit
cmd!ZScanA:
00007ff7`cf4c26d0 48895c2408      mov     qword ptr [rsp+8],rbx
                                          ss:00000068`c5d1e9d0=0000000000000000
0:000> r r8; dd @r8 l1
r8=00000068c5d1ea64
00000068`c5d1ea64  00000017

这次扫描的长度只有^Z之前的5个字符:

0:000> pt
cmd!ZScanA+0x4f:
00007ff7`cf4c271f c3              ret
0:000> dd 68c5d1ea64 l1
00000068`c5d1ea64  00000005

我们期望 file.txt 为 12 个字节,它是:

C:\Temp>for %a in (file.txt) do @echo %~za
12

更一般地说,如果 Windows 控制台程序想要实现类似于 Unix 终端行为的 Ctrl+D 处理,它可以使用宽字符控制台函数 ReadConsoleW , 通过引用传递 CONSOLE_READCONSOLE_CONTROL 结构作为 pInputControl。此结构的 dwCtrlWakeupMask 字段是一个位掩码,用于设置哪些控制字符将立即终止读取。例如,位 4 启用 Ctrl+D。我写了一个简单的测试程序来演示这种情况:

C:\Temp>.\test
Enter some text: line1
You entered: line1\x04

你在上面的例子中看不到这一点,但是这个读取被按 Ctrl+D 立即终止,甚至没有按 enter。 ^D 控制字符(即 '\x04')保留在输入缓冲区中,这在您希望多个控制字符有不同行为的情况下很有用。

关于windows - 如何从命令提示符*不带换行符*发送 EOF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43863509/

有关windows - 如何从命令提示符*不带换行符*发送 EOF?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐