我在以下内容中读到格里莫尔:
一个简单的示例是将“旧”文件中的“白天”更改为“新”文件中的“夜晚”:
sed s/day/night/ <old >new
或者另一种方式(对于 UNIX 初学者),
sed s/day/night/ old >new
为什么作者会认为第一种形式更高级?
我的意思是,与“初学者”语法相比,使用这种形式有什么优点?
答案1
允许 shell 执行open()
类似操作的一个优点是:
utility <in >out
而不是允许命名实用程序执行open()
类似操作:
utility in >out
...文件描述符是安全的前调用指定的实用程序,否则如果在 期间遇到错误open()
,则根本不会调用该实用程序。这是防止可能的竞争条件产生副作用的最佳方法——这种情况在使用时时不时会发生溪流和流编辑器。
如果重定向失败,shell 会短路对该实用程序的调用,并将错误消息写入 stderr -贝壳的stderr 而不是您可能暂时将其定向到该实用程序的任何内容(好吧,这也取决于重定向的命令行顺序)- 采用标准诊断格式。测试是否可以打开文件的最简单方法是打开它,并<
在执行其他操作之前隐式执行此操作。
您问题中的命令中指示的最明显的竞争条件可能涉及出去重定向。在这两种形式中,shell 也会执行>
写打开操作,并且无论是否sed
可以在第二种形式中成功打开读取文件,都会发生这种情况。所以出去被截断——而且可能是不必要的。如果您只想在可以成功打开输入的情况下写入输出,那可能会很糟糕。不过,如果您始终首先打开输入,就像第一种形式中所做的那样,那么这不是问题。
否则,至少有10数字引用的文件描述符可以通过这种方式使用 shell 重定向语法进行操作,并且这些组合可能会变得有点麻烦。
另外,当 shell 执行打开操作时,描述符不属于被调用的命令(与第二个版本相同),而是属于 shell,并且被调用的命令仅继承它。它以与同一复合命令中调用的任何其他命令相同的方式继承,因此命令可以以这种方式共享输入。
答案2
sed
通过 STDIN 和参数来处理文件。
在第一种形式中,您使用输入重定向运算符通过 STDIN传递sed s/day/night/ <old
文件内容。old
sed
在第二种形式 中sed s/day/night/ old
,您只需将文件名作为参数传递给sed
。
两者都是正确的并且会产生相同的输出。
我认为作者的意思是,除非您熟悉标准流及其作用,如何正确使用重定向运算符,否则新用户可能会有点难以习惯第一个,但这只是我的意见,我们无法确定作者在做什么。