han*_*rak 8 command-line shell xargs conventions subshell
许多简单的命令 usingxargs
可以重写为使用子外壳的命令。例如,这是我今天早些时候使用的东西,用于连接 中的 10 个最大的二进制文件/usr/bin
,使用 subshell 与 xargs 编写:
子外壳:
$ cat $(du -sh /usr/bin/* | sort -h | tail | cut -d " " -f 2 | tr "\n" " ")
Run Code Online (Sandbox Code Playgroud)
xargs
:
$ du -sh /usr/bin/* | sort -h | tail | cut -d " " -f 2 | tr "\n" " " | xargs cat
Run Code Online (Sandbox Code Playgroud)
那么什么时候应该使用子shell,什么时候应该使用xargs
?
cut 的分隔符是一个硬制表符,显然在 SE 上无法正确显示。
这是一个有点自以为是的问题,但我只想说,它高度依赖于两件事:
如果您可能运行数十到数百个相同的过程,那么xargs
最有意义。此外,如果这些流程的启动成本很高,xargs
这可能是最好的选择。
但是,如果只有少数命令实例,那么在子 shell 中运行它们就可以了。
如果子shell 生成的参数长度非常长,那么您需要使用xargs
. 但是这个限制非常极端,通常是 2MB-4MB 的字符,所以你不太可能超过它。你可以这样检查:
$ xargs --show-limits < /dev/null
Your environment variables take up 4805 bytes
POSIX upper limit on argument length (this system): 2090299
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2085494
Size of command buffer we are actually using: 131072
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这些命令似乎都不起作用。该cut -d " " -f2
是无效的,cut
只能取一个字符作为分隔符。试试这个:
$ du -sh /usr/bin/* | sort -h | awk 'NR<=10 {print $2}' | tr "\n" " "
-or-
$ du -sh /usr/bin/* | sort -h | tail | cut -f2- | tr "\n" " "
Run Code Online (Sandbox Code Playgroud)
awk
如果您有任何带有空格的文件名或目录,在此处使用可能会导致问题,因此请谨慎使用。
$ ll
total 0
-rw-rw-r--. 1 saml saml 0 Feb 22 19:47 file 1
-rw-rw-r--. 1 saml saml 0 Feb 22 19:47 file 2
$ du -sh * | sort -h | awk 'NR<=10 {print $2}' | tr "\n" " "
file file $
Run Code Online (Sandbox Code Playgroud)
我会使用该cut -f2-
方法,但这只是我,其他人可能会为您提供更复杂的awk
解决方案,但请使用对您最有意义的方法。
注意:当管道输出xargs
不需要调用时cat
,xargs
默认情况下将自动回显它传递的输出。
$ du -sh * | sort -h | tail | cut -f2- | tr "\n" " " | xargs
file 1 file 10 file 2 file 3 file 4 file 5 file 6 file 7 file 8 file 9
Run Code Online (Sandbox Code Playgroud)
如果您使用制表符用 cut 分隔,则不需要明确这样做,它默认为。
-d, --delimiter=DELIM
use DELIM instead of TAB for field delimiter
Run Code Online (Sandbox Code Playgroud)