如果我cat
正确理解手册:
连接文件并在标准输出上打印
cat
将以文件作为参数并将它们打印在标准输出上。
我不明白的是,如果我使用以下命令:
cat img.png > copy.png
我将获得 2 个相同的 png 文件,而如果我只是
cat img.png
我的终端很可能会变得混乱并误解我输入的内容。
- 这怎么可能?
- 二进制值仍然是二进制数据。为什么它不简单地显示一系列 0 和 1 或这些二进制数据的 ASCII 解释或无论终端中的编码是什么?
cat
通过ing 包含奇怪字符的文本文件 也可能出现这种行为吗?- 是否应该实施一种机制来防止这种行为,例如 try{}catch{} 语句?
答案1
cat
连接命令行上作为参数给出的文件并将连接的输出打印到标准输出。它读取字节(从概念上讲,一次一个),并且默认情况下,不对它读取的字节执行任何解释。
在第一个示例中,您将 stdout 重定向到一个文件,这就是您获得一个新文件的原因。
在第二个示例中,字节被写入终端,并且它是终点站即将字符序列解释为终端的控制序列。这就是您的终端上出现异常行为的原因。与以下无关cat
本身。
cat
不知道你将如何处理它的输出。您可能会通过管道将其发送到另一个程序来解释/处理/打印它,或者将其传递给音频驱动程序以播放“雨中曲”。
因此,遵循 Unix 哲学:
做一件事,只做一件事,但要做好
cat
不应试图事后猜测或解释您正在尝试做的事情。
从@Kiwy 的评论如下(针对语法已修复):
这是否意味着如果您的
cat
二进制文件包含诸如 之类的纯文本指令rm -rf
,则可以解释它?
是和不是。让我解释:
否:如果您cat
使用终端,因为它(终端软件)正在将输出发送到您的屏幕,或解释控制序列(它正在模拟旧硬件,例如,电传打字机)。
但:
是的:如果您cat
使用管道并且接收的程序可以将字符解释为命令。
看看这个例子:
cat anyOldShellScript | bash
在此示例中,bash
会将其获取的内容解释为命令,因此rm -rf
如果字符存在于通过 传递到管道的内容中,则运行这些字符cat
。
答案2
我猜发生这种情况主要是因为代码低于 0x20 的不可打印字符。这些是特殊的控制/转义代码,用于 Backspace、Delete 等键。