如何不重复调用cp进程,实现单个源文件批量复制到多个目标文件
核心问题原因
你之前的两个方案分别存在两个问题:
- 循环调用
cp每次启动新进程,百万次进程创建开销远大于文件复制本身开销 - 直接给
cp传多目标参数不符合cp的参数逻辑,cp要求多参数时最后一个参数必须为目标目录
方案1:自定义满足要求的mycp工具
直接实现你要的mycp source dest1 dest2 dest3...调用逻辑,全shell内置操作无额外进程开销:
# 定义mycp函数,可直接写入你的.bashrc永久生效 mycp() { local src="$1" shift # 处理二进制/大文件时去掉content变量,直接在循环里用cp即可 local file_content=$(<"$src") for dest in "$@"; do printf '%s' "$file_content" > "$dest" done }
定义完成后直接执行即可:
mycp source dest.{000000..999999}
提示:如果源文件是大文件或二进制文件,建议把循环内的写入逻辑替换为cp "$src" "$dest",配合批量调用方案使用,避免变量内存占用过高。
方案2:单行命令批量处理(无需自定义函数)
利用tee命令天生支持单输入多输出的特性,配合xargs批量传参,每批仅启动1个tee进程,性能最优:
echo dest.{000000..999999} | xargs -n 1000 sh -c 'tee "$@" < source > /dev/null' sh
参数说明:
-n 1000表示每批传递1000个目标文件名给tee,可根据系统参数长度限制调整大小tee命令会读取一次源文件内容,同时写入当前批次的所有目标文件,完全避免了重复启动cp进程的开销- 该方案天然支持二进制大文件,无转义问题,内存占用极低
方案3:xargs+sh批量循环(兼容性最好)
如果系统对tee参数有长度限制,可使用sh循环批量处理,每批仅启动1个sh进程:
echo dest.{000000..999999} | xargs -n 1000 sh -c 'for dest in "$@"; do cp source "$dest"; done' sh
相比你最初的单次循环启动cp进程的方案,该方案进程数从100万降低到1000个,执行效率提升上千倍。
内容的提问来源于stack exchange,提问作者blueFast
相关产品推荐
相关产品推荐

