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