为什么在二进制文件上使用cat会使终端混乱?


8

如果我cat正确理解手册:

连接文件并在标准输出上打印

cat将文件作为参数并将其打印在标准输出上。
我没有得到的是如果使用以下命令:

cat img.png > copy.png

我将获得2个相同的png文件,如果我只是

cat img.png  

我很有可能会弄乱我的终端并误解我键入的内容。

  • 那怎么可能
  • 二进制值仍然是二进制数据。为什么它不能简单地显示一系列0和1或这些二进制数据的ASCII解释或终端中的编码是什么?
  • 是否可以通过cat打开包含奇怪字符的文本文件来实现此行为?
  • 是否应该实现一种防止这种行为的机制,例如try {} catch {}语句?

2
您的终端不会混乱。它处于您通过发送控制字符来强制进入的状态。更改状态后不能再使用它可能不是您想要的,但这完全是您不了解操作后果的结果。这与在字处理器中将字体颜色切换为绿色,并说您的字处理器被弄乱一样,只是因为不知道如何在不退出程序的情况下将其切换回黑色字体。
Anthon 2014年

4
一个reset命令有时可能会有所帮助,但是这是没有灵丹妙药。
Ouki 2014年

要键入的实际顺序是Control-J重置Control-J。几乎总是恢复理智。
2015年

1
@Joshua那么lone resetresetCtrl-J按键之间有什么区别?我看不到任何内容(也没有任何理由采取更复杂的方式)
语法错误

1
因为如果终端处于RAW模式,Enter会生成Ctrl-M而不是Ctrl-J,因此外壳看不到结束行并运行命令所必需的击键。
2015年

Answers:


8

cat 将命令行中作为参数提供的文件连接到标准输出,它一次读取字节,因为默认情况下不对读取的字节进行任何解释。

在第一个示例中,您将标准输出重定向到文件,这就是为什么要获取新文件的原因。

在第二个示例中,字节被写入终端,并且终端将字符序列解释为终端的控制序列,这就是为什么您在终端上出现异常行为的原因。它与它无关catcat也不知道您将如何处理它的输出。您可能正在通过管道将其发送到另一个程序,以进行解释/处理/打印或播放“在雨中唱歌”。

因此,遵循Unix哲学,

做一件事,只做一件事,但要做好

cat 不应试图再次猜测您要做什么。

编辑以下对@kiwy的第一条评论的回复。

是和否,让我解释一下,

否,如果您cat使用的是终端,因为它(终端软件)正在将输出发送到屏幕或解释控制序列(它在模仿旧的硬件,例如电传打字设备)。

但,

是的,如果您选择管道,则接收程序可以将字符解释为命令。

以这个为例,cat anyOldShellScript | bashbash将解释它作为命令得到的内容。


这是否意味着如果您cat可能在这样的纯文本指令中包含一个二进制文件,则rm -rf .可以对其进行解释?
2014年

我接受答案,尽管我真的不明白为什么如果我在键盘上输入像dumbass那样的终端会像这样混乱,我将永远无法得到它:D
Kiwy 2014年

现在具有讽刺意味的是……哼
Kiwy 2014年

1
@Kiwy控制字符在您的键盘上不存在,但是您可以echo选择输出它们。见 stackoverflow.com/questions/5947742/...对于如何做到这一点,并termsys.demon.co.uk/vtansi.htm一些什么是可能的
戴维·威尔金斯

@DavidWilkins嘿,谢谢,这太好了,需要学习的东西太多了,没有时间:-(
Kiwy 2014年

2

我猜这主要是由于代码低于0x20的不可打印字符引起的。这些是特殊的控制/转义代码,用于退格键,删除键等键。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.