【问题标题】:Writing Non-Standard Characters Into Linux Command Line将非标准字符写入 Linux 命令行
【发布时间】:2013-12-22 22:54:21
【问题描述】:

我遇到了一些问题。为了做我正在尝试的事情,我需要能够在不使用 IO 重定向的情况下将纯十六进制值输入到命令行的标准输入中(特别是输入到程序内部的 gets() 调用中)。我通常通过使用 ctrl + u + number 输入与输入的十六进制值等效的 ascii 字符来获得成功,但我需要能够输入终端忽略或解释为操作而不是字符的空字符/退格/等.如果我使用管道或 IO 重定向,在初始输入和程序关闭后我无法与程序交互。有人有什么想法吗?我认为可能的解决方案是:

  1. 想办法手动输入字符并保留它们
  2. 找到一种方法来输入不是 unicode 或 ascii 但仍将被接受为字节信息的字符
  3. 找到一种方法,将输入通过管道或重定向到被解释为来自命令行的程序,然后以某种方式说服它立即将输入控制权交还给命令行

我什至不确定第三个是否可能或有用,因为我不完全确定如果程序直接从命令行以外的任何地方获取信息,为什么程序不工作,我只知道我必须手动输入,否则无法运行。有人对这 3 个选项中的任何一个或您能想到的任何其他选项有任何想法吗?我被难住了。

(哦,还有,如果有人能解释为什么有时 ctrl+u+number 会输出与输入的数字完全不同的十六进制值的字符,我很好奇,但我认为它不会帮助我反正目前的问题。)

【问题讨论】:

  • “完全不同的十六进制值”?
  • 我的意思是,例如,我输入 ctrl+u+4748,如果我用 xxd 查看它的值类似于 c0f9。
  • xxd 显示用于编码字符的字节,而不是 Unicode 代码点。
  • 啊,我没有意识到两者之间存在差异。我将如何从字节创建一个字符,以便它的编码是我想要的,而不是它的代码点?
  • 一般不用,因为输入法会帮你转换。

标签: linux unix unicode io ascii


【解决方案1】:

您可以将您的tty 切换到raw(未煮过的)模式,然后将所有键入的字符传递给程序而无需任何处理:

$ stty raw
$ command ...
$ stty -raw

键盘完全可以使用 Control@ 发送空的 00 字节,但是,无法使用 gets 读取它这看起来是您使用的,请确保您逐个字符地处理字符串,而不是作为字符串,因为00 在后一种情况下被视为终止符..

04 在原始模式下是 ControlDControlVControlD 处于熟化模式

05ControlE 但可能会被您的终端仿真器拦截,在这种情况下您必须禁用快捷方式或使用其他仿真器。

08 在原始模式下是 ControlHControlVControlH 处于熟化模式

74 只是 t

84 不是有效的 UTF-8 字符。您仍然可以通过以下方式将此字节传输到您的程序中:

printf "\204" | command

【讨论】:

  • 我绝对不精通这个命令,所以也许我做错了什么,但这似乎并没有达到我想要的效果。它适用于非常基本的命令行,但我正在尝试将信息输入到具有 gets() 调用的程序中,并且有了这个,我永远无法发送新行来结束我的输入(而且,它没有根本无法帮助我输入不可打印的字符)。
  • 我明白了,原始模式禁用 Ctrl-U 处理,这会破坏(至少部分)您正在寻找的内容。关于新行,您需要输入 Control-J 作为 Enter 发送回车,这不是所期望的。
  • 我刚刚检查过,即使在原始模式下,Control-shift-u 仍然有效。您应该澄清导致问题的字符。
  • 我想我现在的问题更多了,因为从上面的 cmets 我了解到 ctrl+u+hex 值不一定编码为该十六进制值,我需要知道如何输入字符从键盘输入十六进制值 00、05、04、08、74 和 84。其中一些是常见的(08 是退格键,00 是空值),但据我所知,其他一些不是,也没有定义的快捷方式。如果我有办法输入这些字符,这个 stty raw 解决方案就可以了。
  • 001F 之间的所有字符都有快捷方式。答案已更新。
猜你喜欢
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多