从https://unix.stackexchange.com/a/458074/674
记住
--
在将任意参数传递给命令时使用(或在可能的情况下使用重定向)。因此,sort -- "$f1"
或更好的sort < "$f1"
替代sort "$f1"
。
为什么首选使用--
和重定向?
为什么sort < "$f1"
优先于sort -- "$f1"
?
为什么 sort -- "$f1"
优先于sort "$f1"
?
谢谢。
从https://unix.stackexchange.com/a/458074/674
记住
--
在将任意参数传递给命令时使用(或在可能的情况下使用重定向)。因此,sort -- "$f1"
或更好的sort < "$f1"
替代sort "$f1"
。
为什么首选使用--
和重定向?
为什么sort < "$f1"
优先于sort -- "$f1"
?
为什么 sort -- "$f1"
优先于sort "$f1"
?
谢谢。
Answers:
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
本次cmd
stdin是无法映射/查找的管道与之混淆。
sort
顺序读取数据,而您将无法读取mmap
文件。虽然sort
可能不会有太大问题吧,考虑的性能less <file
和less file
。在第一种情况下,less
必须将文件的全部内容保留在内存中,在第二种情况下,只允许读取所需的部分。现在想象这file
是一个100GB的日志文件...
less <file
将所有文件保留在内存中,但这不是强制性的,这是一个不足之处。只有cat file | less
被迫。签出less /dev/fd/0 <f
,即使文件是在stdin上接收的,也不会将文件保留在内存中。一个普遍的误解是,Unix中的stdin不可搜索。实际上,根据文件类型,它可能是可搜索的。
read()
从文件中顺序读取数据,而mmap()
一次将整个文件读取到内存中吗?
sort
POSIX)都支持它。但是确实并不总是支持它。
getopt()
C函数的POSIX规范认识到该参数的重要性--
。但是要点是您接受的观点:参数处理是各个程序的领域,而不是全部都--
专门对待。
问题是文件名以短划线开头。sort "$f1"
如果f1
开头为的值将不起作用,-
因为该命令会将值解释为一个选项。这通常会导致错误,但是甚至可能导致安全漏洞。使用sort -- "$f1"
,双破折号参数--
表示“在此点之外没有选项”,因此的值f1
将不会被解释为选项。但是仍然有一个极端的情况:如果的值f1
是一个破折号而不是其他任何东西,则它不是一个选项,而是参数-
,表示“标准输入”(因为该参数是输入文件;对于输出文件)这意味着“标准输出”)。
使用重定向避免了所有这些陷阱。
这适用于大多数命令,而不仅仅是sort
。
sort < "$f1"
如果值等于会起作用-
吗?我尝试过的任何外壳都没有。
seq 10 > -; sort -
用seq 10 > -; sort < -
。