以前的代码:
total=`ls -Rp rootfs | wc -l`
count=0
Run Code Online (Sandbox Code Playgroud)
当我为变量分配一个简单的加法时:
sudo find rootfs -exec cp -d -- "{}" "/media/$USER/{}" 2> /dev/null \; -exec sync \; -exec count=$((count+1)) \; -exec echo -en "\rcopiati: $count/$total" \;
Run Code Online (Sandbox Code Playgroud)
我得到:
find: ‘count=1’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
同样当我执行:
sudo find rootfs -exec cp -d -- "{}" "/media/$USER/{}" 2> /dev/null \; -exec sync \; -exec count=1 \; -exec echo -en "\rcopiati: $count/$total" \;
Run Code Online (Sandbox Code Playgroud)
我犯了同样的错误。为什么?
对于复制的每个文件,我想要计数器:1/13444,即更新为 2/13444、3/13444 等...
编辑:
我找到了一种方法,但它看不到隐藏文件,如何让他们在 for 循环中看到它们?
#!/bin/bash
copysync() {
countfiles() {
for f in $1/*; do
if [ -d "$f" ]; then
countfiles "$f"
else
if [ "${f: -2}" != "/*" ]; then
total=$((total+1))
fi
fi
done
}
recursivecp() {
for f in $1/*; do
if [ -d "$f" ]; then
mkdir -p "/media/$USER/$f"
recursivecp "$f"
else
if [ "${f: -2}" != "/*" ]; then
sudo cp -a "$f" "/media/$USER/$f"
sudo sync
count=$((count+1))
echo -en "\rCopied: $((count*100/total))%"
fi
fi
done
}
total=0
countfiles $1
count=0
recursivecp $1
}
copysync rootfs
Run Code Online (Sandbox Code Playgroud)
外壳count=$((count+1))
在运行之前展开find
。
然后find
将尝试将参数-exec
作为命令执行。这必须是程序或脚本,不能是用于变量赋值的 shell 内置或 shell 语法。
以这种方式计算找到的文件不会起作用,因为为find
启动了一个新进程-exec
,因此变量赋值的结果在父 shell 中将不可用。
我建议打印为找到的每个文件和管道的输出线find
来wc -l
,例如
find rootfs -exec cp -d -- "{}" "/media/$USER/{}" \; -exec sync \; -print|wc -l
Run Code Online (Sandbox Code Playgroud)
要在复制文件时获得一些输出,您可以使用以下内容:
find rootfs|while IFS= read -r file
do
cp -d -- "$file" "/media/$USER/$file"
sync
count=$((count+1))
echo -en "\rcopiati: $count/$total"
done
Run Code Online (Sandbox Code Playgroud)
评论:
这不适用于包含换行符(可能还有其他特殊字符)的文件名。
如果rootfs
包含子目录,脚本可能不起作用。您应该处理这种情况或使用find
's options-maxdepth
并-type f
避免此问题。