-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 に答える