Bash 脚本错误

Bash 脚本错误

我在尝试备份此目录中的每个 .qcow2 扩展名时遇到错误。如何以不同的方式备份目录中的所有内容?

这是我的脚本和错误:

#!/bin/bash

for (( i =1; i<5; i++))
    do
            gzip < /var/lib/libvirt/images/*.qcow2 > /root/bin/backup/full/vm$i.qcow2.backup.gz
    done

./assnBackup.bash: line 5: /var/lib/libvirt/images/*.qcow2: ambiguous redirect
./assnBackup.bash: line 5: /var/lib/libvirt/images/*.qcow2: ambiguous redirect
./assnBackup.bash: line 5: /var/lib/libvirt/images/*.qcow2: ambiguous redirect
./assnBackup.bash: line 5: /var/lib/libvirt/images/*.qcow2: ambiguous redirect

foreach 脚本:

#!/bin/bash

i=0

for f in /var/lib/libvirt/images
    do
            gzip < $f > /root/bin/backup/full/vm$i.qcow2.backup.gz
            i=$((i++))
    done

使固定:

#!/bin/bash

i=0

file=/var/lib/libvirt/images/*

for f in $file
do
gzip < $f > /root/bin/backup/full/vm$i.qcow2.backup.gz
    i=$((i + 1))
done

答案1

好吧,那么。

如果目录中有多个文件,将尝试重定向所有文件gzip < /.../*.qcow2的输入。gzip这是不可能的,所以 Bash 会给出错误。如果该模式仅匹配一个文件,则该模式会起作用。

在第二个中,你有for f in /var/lib/libvirt/images.好吧,for迭代列出的单词,这里只有一个。它本身不会迭代目录的内容:它也可以用于其他内容,例如for s in foo bar blah ; do echo $s ; done.因此,您需要明确告诉 shell 使用通配符模式扩展其中的所有文件名。for f in /var/lib/libvirt/images/*.qcow2将为名称以 结尾的每个文件运行一次循环.qcow2,并f保存文件名。


现在,这应该gzip至少可以工作了。尽管我仍然想知道在进行备份副本时您是否真的想放弃原始文件名。

你可以这样做:

gzip -k "$f" && mv "$f.gz" /root/bin/backup/full/

gzip默认情况下会创建一个压缩文件,其扩展名.gz附加在原始文件名上。通常,它也会删除原始文件,但-k告诉它保留它。然后我们将压缩的副本移走。所以foo.qcow2 会成为foo.qcow2.gz备份目录中。

不过,如果备份目录位于不同的文件系统上(应该如此),则上述操作确实涉及将压缩文件写入两次。 shell 中的一些字符串操作可以解决这个问题:

gzip "$f" > "/root/bin/backup/full/${f##*/}.gz"

当然,您也可以使用tar一次归档整个目录,但对于 VM 映像来说,使用起来可能有点尴尬,因为无法随机访问从压缩的 tar 归档中提取单个文件。

相关内容