在 Vidar Holen 的博客文章中dd 无用的使用,他认为这dd
实际上是无用的,主要是因为一切都是文件并且文件可以通过管道传输。
我们还经常在所有 *nix 网站上看到对使用cat
.
然而,随后维达尔提出了这个例子:
# Rip a cdrom to a .iso file
cat /dev/cdrom > myfile.iso
...我想知道,是否可以做到这一点不使用cat
?
显然,POSIX shell 假定第一组字符是一个命令(因此“[”=“test”等),这在具有就地运算符的现代语言中是不常见的。而且,作为 shell 实际上是一个解释器,为什么我们没有达到cat
和都是多余的地步呢dd
?
是否有任何基于 POSIX 的 shell 完全实现了就地运算符,足以/dev/cdrom > myfile.iso
将数据从设备复制到文件?
或者
POSIX 规范中是否有什么东西使得这种功能不可能实现?
请注意,此问题与 UUOC 问题略有不同,因为该示例仍然在开头使用命令(“<”)而不是就地运算符。所以它仍然符合第一个单词是命令的规则。
(顺便说一句,我个人喜欢 dd,因为如果没有它,说威尔士语就会少很多乐趣。:-p)
答案1
兹什:
</dev/cdrom >myfile.iso
将仅使用运算符来执行此操作(当不在sh
仿真中时)。不过,它仍然运行$NULLCMD
命令(cat
默认情况下)来进行实际的读写。
您建议的语法
/dev/cdrom > myfile.iso
实际上可以工作现在在任何 POSIX shell 中 - 因为它根本不一定涉及 shell。
所要求的是它/dev/cdrom
是可执行的,并且在执行时输出CD的内容。这是您的内核或设备驱动程序可以提供的东西。或者,系统可以execl
(和朋友)使用/dev/cdrom
或其内容作为启动的密钥其他具有该文件名的可执行文件(例如cat
)。
无论哪种情况,只要有适当的exec
能力,/dev/cdrom
您绝对能够在任何 shell 中运行该命令。我不知道有哪个系统确实会这样做,可能有很好的理由,但它在理论上是允许的和可能的。
POSIX
POSIX 要求将命令的第一个单词视为命令名称,并且它定义了该命令必须如何运行:
shell 应在单独的实用程序环境中执行该实用程序,其操作相当于调用 POSIX.1-2017 系统接口卷中定义的 execl() 函数,并将路径和 arg0 参数设置为命令名称 [...]
如果 execl() 函数由于与 [ENOEXEC] 错误等效的错误而失败,则 shell [...] 应写入一条错误消息并应返回退出状态 126。
因此,不允许一致的 shell 打开并打印文件中的数据。然而,shell 不能作为非 POSIX 扩展支持该行为并没有什么特殊原因。我怀疑您提出的形式有重大缺点,但 zsh 的版本基本上没问题。