bash脚本如何扩展文件globs?

时间:2013-01-20 13:49:30

标签: bash tar glob

在这段代码中,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

1 个答案:

答案 0 :(得分:1)

抑制globbing的常用技巧是将字符串括在双引号中(当你想要扩展反引号或变量时)或单引号(当你不需要时)。所以在这里,您将消除$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