为什么`sort <“ $ f1”`优先于`sort-“ $ f1”`,为什么它优先于`sort“ $ f1”`?


29

https://unix.stackexchange.com/a/458074/674

记住-- 在将任意参数传递给命令时使用(或在可能的情况下使用重定向)。因此,sort -- "$f1"或更好的sort < "$f1"替代sort "$f1"

为什么首选使用--和重定向?

为什么sort < "$f1"优先于sort -- "$f1"

为什么 sort -- "$f1"优先于sort "$f1"

谢谢。


Answers:


55
sort "$f1"

失败了的值$f1与启动-或这里的情况下,sort一些与启动+(可以有一个名为严重的后果,-o/etc/passwd例如)。

sort -- "$f1"

(其中-- 信号选项的结束)地址的这些问题,但大多数仍不能为所谓的文件-(这sort解释为是指它的标准输入代替)。

sort < "$f1"

没有那些问题。

在这里,是打开文件的外壳。这也意味着,如果无法打开该文件,您还将收到一条可能更有用的错误消息(例如,大多数外壳程序将在脚本中指示行号),并且如果您使用重定向尽可能打开文件。

而在

sort < "$f1" > out

(与相反sort -- "$f1" > out),如果"$f1"无法打开,out则不会被创建/截断,sort甚至无法运行。

为了消除一些可能的混乱(以下注释),只要文件本身是可查找的,这不会阻止命令mmap()进入文件或lseek()进入文件内部(sort两者均不会)。唯一的区别是,该文件由外壳先打开,并在文件描述符0上打开,而以后可能在另一个文件描述符上的命令打开。该命令仍然可以根据需要查找/映射fd 0。请勿将cat file | cmd本次cmdstdin是无法映射/查找的管道与之混淆。


4
请记住,使用重定向会强制sort顺序读取数据,而您将无法读取mmap文件。虽然sort可能不会有太大问题吧,考虑的性能less <fileless file。在第一种情况下,less必须将文件的全部内容保留在内存中,在第二种情况下,只允许读取所需的部分。现在想象这file是一个100GB的日志文件...
聚苯乙烯泡沫塑料飞

7
@styrofoamfly:正确的做法是less <file将所有文件保留在内存中,但这不是强制性的,这是一个不足之处。只有cat file | less被迫。签出less /dev/fd/0 <f,即使文件是在stdin上接收的,也不会将文件保留在内存中。一个普遍的误解是,Unix中的stdin不可搜索。实际上,根据文件类型,它可能是可搜索的。

@styrofoamfly您的意思是read()从文件中顺序读取数据,而mmap()一次将整个文件读取到内存中吗?
蒂姆(Tim)

1
@JohnBollinger否。这至少可以追溯到1980年从SysIII的getopt开始GNU项目开始之前,并且要求大多数标准实用程序(包括sortPOSIX)都支持它。但是确实并不总是支持它。
斯特凡Chazelas

2
抱歉,@StéphaneChazelas,您对约定的由来是正确的,此外,我还将规定getopt()C函数的POSIX规范认识到该参数的重要性--。但是要点是您接受的观点:参数处理是各个程序的领域,而不是全部都--专门对待。
John Bollinger

17

问题是文件名以短划线开头。sort "$f1"如果f1开头为的值将不起作用,-因为该命令会将值解释为一个选项。这通常会导致错误,但是甚至可能导致安全漏洞。使用sort -- "$f1"双破折号参数--表示“在此点之外没有选项”,因此的值f1将不会被解释为选项。但是仍然有一个极端的情况:如果的值f1是一个破折号而不是其他任何东西,则它不是一个选项,而是参数-,表示“标准输入”(因为该参数是输入文件;对于输出文件)这意味着“标准输出”)。

使用重定向避免了所有这些陷阱。

这适用于大多数命令,而不仅仅是sort


您是说sort < "$f1"如果值等于会起作用-吗?我尝试过的任何外壳都没有。
grawity

@grawity,比较seq 10 > -; sort -seq 10 > -; sort < -
斯特凡Chazelas
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.