这个 zsh 对“参数列表太长”的解决方案有什么作用?

Ame*_*ina 6 zsh files

我在@Gilles 的回答中读到了以下内容:

在 zsh 中,您可以加载mv内置函数:

setopt extended_glob
zmodload -Fm zsh/files b:zf_\*
mv -- ^*.(jpg|png|bmp) targetdir/
Run Code Online (Sandbox Code Playgroud)

作为"mv: Argument list too long”问题的解决方案。答案建议使用 zsh mv(而不是 GNU),但这行到底是做什么的?:

zmodload -Fm zsh/files b:zf_\*
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 13

查看 zsh 文档的最佳方法是使用info.

如果您运行info zsh,您可以使用索引(想想一本书的索引)来定位描述zmodload命令的部分。

i,然后您可以进入zmo并按Tab。您将直接进入zmodload内置描述,它将告诉您所有相关信息。

简而言之,zmodload -F加载模块(如果未加载)并仅启用该模块的指定功能

使用-m,我们在m此处启用了匹配模式的功能b:zf_*b:用于内置,因此上述命令加载zsh/files模块(info -f zsh -n 'The zsh/files Module,'有关详细信息,请参阅有关该模块的详细信息)并且仅启用名称以zf_.

zmodload -F zsh/files
Run Code Online (Sandbox Code Playgroud)

加载模块,但不启用任何功能:

$ zmodload -FlL zsh/files
zmodload -F zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync -b:zf_chgrp -b:zf_chown -b:zf_ln -b:zf_mkdir -b:zf_mv -b:zf_rm -b:zf_rmdir -b:zf_sync
Run Code Online (Sandbox Code Playgroud)

列出该模块的功能,指定当前启用的功能(暂时没有)。你会注意到 amvzf_mvbuiltin。

$ zmodload -mF zsh/files 'b:zf_*'
$ zmodload -FlL zsh/files
zmodload -F zsh/files -b:chgrp -b:chown -b:ln -b:mkdir -b:mv -b:rm -b:rmdir -b:sync +b:zf_chgrp +b:zf_chown +b:zf_ln +b:zf_mkdir +b:zf_mv +b:zf_rm +b:zf_rmdir +b:zf_sync
Run Code Online (Sandbox Code Playgroud)

您会注意到zf_mv已启用内置函数,但未启用mv(其他内置函数相同)。这意味着,系统命令的那些内置版本已经启用,但没有覆盖系统命令:

$ type zf_mv
zf_mv is a shell builtin
$ type mv
mv is /bin/mv
Run Code Online (Sandbox Code Playgroud)

现在你有一个 builtin mvaszf_mv, not mv,你可以这样做:

zf_mv -- ^*.(jpg|png|bmp) targetdir/
Run Code Online (Sandbox Code Playgroud)

因为zf_mv是内置的,所以没有execve()系统调用,所以你不会达到Too many args与之相关的限制。

当然,你也可以这样做:

zmodload zsh/files # without -F, all the features are enabled
mv -- ^*.(jpg|png|bmp) targetdir/
Run Code Online (Sandbox Code Playgroud)

但请注意,mvzsh内置等效项替换系统。

为了克服E2BIG execve()错误(执行外部命令时参数过多),zsh还提供了一个zargs函数。

你跑:

autoload zargs # in ~/.zshrc if you use it often
Run Code Online (Sandbox Code Playgroud)

将其标记为自动加载。

然后你可以使用:

zargs -- ^*.(jpg|png|bmp) -- mv -t targetdir/
Run Code Online (Sandbox Code Playgroud)

(这里假设 GNUmv作为-t选项)。zargsmv根据需要运行尽可能多的命令以避免 E2BIG(就像xargs会做的那样)。