-2

在此代码中,该excludespec变量应与它的所有子字符串匹配,但它似乎在执行时评估匹配它的实际文件,而不是将其精确表示传递给使用它的 tar 命令。

excludespec=${PWD##*/}\_$USER\_`hostname`.bkcd_backup*

最终结果是正在创建的存档与排除列表不匹配,因此 tar 输出:

tar: .: file changed as we read it

定义它的字符串是否在做我不知道的事情?

这是代码:

#!/bin/sh
# bkcd - backup current directory in situ

DMY_M() {
  date +%Y%m%d_%H%M
}

timestring=$(DMY_M)
echo `pwd` - $timestring > .bkcdspec  
filename=${PWD##*/}\_$USER\_`hostname`.bkcd_backup.$timestring.tar.gz    
excludespec=${PWD##*/}\_$USER\_`hostname`.bkcd_backup*
fullexclude="$excludespec"tar.gz    
echo excludespec - $excludespec
echo filename - $filename
echo fullexclude - $fullexclude    
tar -cpzf $filename --exclude=$fullexclude .
rm .bkcdspec
4

1 回答 1

1

抑制通配的常用技巧是将字符串括在双引号中(当您想要扩展反引号或变量时)或单引号(当您不想要时)。因此,在这里,您将消除$excludespec并设置$fullexclude

fullexclude="${PWD##*/}_${USER}_$(hostname).bkcd_backup*.tar.gz"

并将其用作:

tar -cpzf "$filename" --exclude="$fullexclude" .

(如果没有双引号"$fullexclude",如果你碰巧有一些文件被命名--exclude=...value-of-$fullexclude,你会感到惊讶。你不太可能有这样的文件,但你最好在它出现之前阻止它。)

请注意,当您为调试而回显时,停止通配也很重要。再次,双引号:

echo "filename=$filename"
echo "fullexclude=$fullexclude"   

否则,echo会在名称上进行全局扩展,再次使您感到困惑。

将这些变化放在一起会导致:

#!/bin/sh
# bkcd - backup current directory in situ

timestring=$(date +%Y%m%d_%H%M)
echo "$(pwd) - $timestring" > .bkcdspec
prefix="${PWD##*/}_${USER}_$(hostname).bkcd_backup"
filename="$prefix.$timestring.tar.gz"   
fullexclude="$prefix.*.tar.gz"
echo "filename - $filename"
echo "fullexclude - $fullexclude"   
tar -cpzf "$filename" --exclude="$fullexclude" .
rm .bkcdspec
于 2013-01-21T01:45:20.187 回答