Linux/UNIX:Shell错误中的rm,cp,mv命令参数列表过长错误
时间:2020-01-09 10:43:29 来源:igfitidea点击:
我们有一个备份服务器,大多数开发人员使用sftp或者ftp上传文件。我只需要备份最近四个星期。如果我尝试列出或者删除目录,则会出现错误,无法删除目录。我正在获取参数列表消息太长。在bash/ksh/csh/tcsh/zsh shell中执行命令时,如何解决此问题?在Linux和类似UNIX的系统下,每个命令都接受一个通常称为命令参数(或者args)的参数。例如,命令cd/etc具有一个命令行参数,即/etc。某些命令可以接受两个以上的参数,并对提供的参数起作用。例如,考虑以下cp命令:cp/etc/file1/etc/file2/etc/file3/mnt/pen
cp命令共有四个命令行参数。
该shell程序最多可容纳131072字节的命令行参数。
如果您尝试传递的数字超过该数字,则会出现如下错误:
Argument list too long
参数列表太长
请记住,每个字符都需要一个字节的存储空间。
找出命令行参数的最大长度
在Linux内核中,命令行参数的最大长度限制为 128k
要查找您的限制,请执行:
getconf ARG_MAX
输出示例:
2621440
该限制影响execve()内核函数,所有其他exec()函数(execl,execlp,execle等)都将使用该内核函数。
选项#1:在使用rm,ls,cp,mv或者任何其他Shell命令时,如何解决参数列表过长的错误问题
解决此问题的最佳方法是find和xargs命令的组合。
语法为:
find /dir/to/search -type f -name 'file-pattern' -print0 | xargs -0 -n 10 command-name find /dir/to/search -type f -iname "*.EXT" -print0 | xargs -0 command-name find /dir/to/search -type f -iname "*.EXT" -command
当您收到参数列表过长的错误时仅列出文件
使用以下任一语法仅列出文件
find /dir/to/search -type f -iname "*.EXT" -ls find /nas01/data/ -type f -iname "*.doc" -ls
或者以下可移植语法:
find /nas01/data/ -name '*.doc' -exec ls {} + ## GNU/Find ## find /nas01/data/ -type f -name '*.doc' -exec ls -l {} +
为了避免递归,请使用以下GNU查找选项:
find /nas01/data/ -name '*.doc' -maxdepth 1 -exec ls -l {} +
仅当参数列表过长错误时删除文件
语法如下:
# GNU/find and BSD/find Jan not work on older *nix find /dir/to/search -type f -iname "*.EXT" -delete find ~/Downloads/ -type f -iname "*.avi" -delete find ~/Projects/ -type f -iname "*.pdf" -delete ## use xargs and rm command ## find ~/Downloads/ -name '*.avi' -print0 | xargs -0 -n 10 rm -f
更可移植的语法:
find ~/Projects/ -name '*.pdf' -exec rm -vf {} +
为了避免递归,请使用以下GNU查找选项:
## GNU find and Jan work with bsd find too ## find ~/Projects/ -name '*.pdf' -maxdepth 1 -exec rm -f {} + find ~/Downloads/ -type f -iname '*.avi' -print0 | xargs -0 -n 10 rm -f
您还可以使用GNU并行命令:
## man parallel for more ## find ~/Downloads/ -type f -iname '*.avi' -print0 | parallel -X -0 rm -vf
其中:
-name" * .pdf"
:搜索模式。-type f
:仅匹配文件。-print 0
:处理带有空格,,\,制表符和换行符的怪异文件名时,避免令人讨厌的惊喜。 -print0主目录与xargs -0结合使用可有效处理奇怪的文件名。-maxdepth 1
:最多在命令行参数下下降一个目录级别,即避免递归。-exec rm -f {} +
或者-exec ls {} +
:在尽可能多的文件上运行rm或者ls命令。
选项#2:循环使用shell程序,以避免arg列表过长的错误
语法如下,它非常慢,可能根本无法工作:
for f in *; do command "$i"; done ## delete all pdf files ## for f in *.pdf; do /bin/rm -rf "$f"; done ############################################################################ ### Delete all *.mp4 and *.avi files using pure Bash solution using arrays ### Based on http://mywiki.wooledge.org/BashFAQ/095 ############################################################################ files=($HOME/Downloads/*.avi $HOME/Downloads/*.mp4) for ((i=0; i<${#files[*]}; i+=100)); do /bin/rm -vf "${files[@]:i:100}" done
命令摘要,以避免在shell中限制
## deals with weird filenames too ## find /dir/to/search/ -name "file-pattern-search" -exec command {} + ## find and xargs based solution ## find /dir/to/search/ -name "file-pattern-search" -print0 | xargs -0 command ## For gnu parallel fans ## find /dir/to/search/ -name 'file-pattern-search' -print0 | parallel -X -0 command ## older and not recommended solution; but kept here for the historical reasons only ## for i in *; do command "$i"; done