バックアップにmake
とtar
を使用しています。 makefileを実行すると、tarコマンドはfile changed as we read it
を表示します。この場合、
--ignore-failed-read
は役に立ちません。 MinGWでtar 1.23を使用しています警告の後にバックアップを停止するには、tarの警告を停止するにはどうすればよいですか?
編集-2:それが理由かもしれません
上で言ったように、bash Shellスクリプトは私の古いコンピューターでうまく機能しました。古いコンピューターと比較すると、msys
バージョンは異なります。 tarコマンドのバージョンも同様です。古いコンピューターでは、tarは1.13.19で、新しいコンピューターでは1.23です。依存関係のmsys-1.0.dllを新しいコンピューターにコピーせずに古いtarコマンドをコピーし、名前をtar_oldに変更しました。また、シェルスクリプトのtarコマンドを更新し、スクリプトを実行しました。その後、すべてが大丈夫です。そのため、問題はtarコマンドにあるように見えました。風袋引きの際にファイルが変更されることはないと確信しています。新しいバージョンのtarコマンドのバグですか?知りません。
編集-1:詳細を追加
バックアップは、bashシェルスクリプトによって呼び出されます。ターゲットディレクトリをスキャンしてmakefileをビルドし、makeを呼び出してバックアップにtarコマンドを使用します。次に、bashシェルスクリプトによって作成された典型的なメイクファイルを示します。
#--------------------------------------------
# backup VC
#--------------------------------------------
# the program for packing
PACK_TOOL=tar
# the option for packing tool
PACK_OPTION=cjvf
# M$: C driver
WIN_C_DIR=c:
# M$: D driver
WIN_D_DIR=d:
# M$: where the software is
WIN_PRG_DIR=wuyu/tools
# WIN_PRG_DIR=
# where to save the backup files
BAKDIR=/home/Wu.Y/MS_bak_MSYS
VC_FRAMEWORK=/home/Wu.Y/MS_bak_MSYS/tools/VC/VC_framework.tar.bz2
VC_2010=/home/Wu.Y/MS_bak_MSYS/tools/VC/VC_2010.tar.bz2
.PHONY: all
all: $(VC_FRAMEWORK) $(VC_2010)
$(VC_FRAMEWORK): $(WIN_C_DIR)/$(WIN_PRG_DIR)/VC/Framework/*
@$(PACK_TOOL) $(PACK_OPTION) "$@" --ignore-failed-read /c/$(WIN_PRG_DIR)/VC/Framework
$(VC_2010): $(WIN_C_DIR)/$(WIN_PRG_DIR)/VC/VS2010/*
@$(PACK_TOOL) $(PACK_OPTION) "$@" --ignore-failed-read /c/$(WIN_PRG_DIR)/VC/VS2010
ご覧のとおり、tarパッケージは〜/ MS_bak_MSYS/tools/VC/VC_2010.tar.bz2に保存されています。 〜/ qqaaでスクリプトを実行します。 ~/MS_bak_MSYS
はtarコマンドから除外されます。そのため、私が作成しているtarファイルは、tarファイルに入れようとしているディレクトリ内にありません。これが、警告が出たのがおかしいと感じた理由です。
また、「読むと変更される」というtarメッセージが表示されます。私にとって、これらのメッセージは、bitbakeビルド環境でLinuxファイルシステムのtarファイルを作成していたときに発生しました。このエラーは散発的でした。
私にとって、これは同じディレクトリからtarファイルを作成したためではありません。実際には、tarファイルの作成中に上書きまたは変更されたファイルがあると想定しています。
メッセージは警告であり、tarファイルを作成します。オプションを設定することにより、これらの警告メッセージを抑制することができます
--warning=no-file-changed
( http://www.gnu.org/software/tar/manual/html_section/warnings.html )
それでも、警告メッセージの場合、tarが返す終了コードは「1」です。 http://www.gnu.org/software/tar/manual/html_section/Synopsis.html
したがって、スクリプト内の関数からtarファイルを呼び出す場合、次のような終了コードを処理できます。
set +e
tar -czf sample.tar.gz dir1 dir2
exitcode=$?
if [ "$exitcode" != "1" ] && [ "$exitcode" != "0" ]; then
exit $exitcode
fi
set -e
非常に遅いですが、私は最近同じ問題を抱えていました。
問題は、コマンドの実行後に.
が作成されるため、dir xyz.tar.gz
が変更されるためです。 2つの解決策があります。
解決策1:tar
は、.
内の任意のディレクトリにアーカイブが作成されていてもかまいません。ワークスペース外でアーカイブを作成できない理由があります。次のようにアーカイブを置くための一時ディレクトリを作成することにより、この問題を回避しました。
mkdir artefacts
tar -zcvf artefacts/archive.tar.gz --exclude=./artefacts .
echo $?
0
解決策2:これが好きです。 tarを実行する前にアーカイブファイルを作成します。
touch archive.tar.gz
tar --exclude=archive.tar.gz -zcvf archive.tar.gz .
echo $?
0
このような問題のデバッグを支援したい場合は、makeルールまたは少なくとも起動したtarコマンドを提供する必要があります。表示するコマンドがない場合、コマンドの何が問題なのかをどのように確認できますか?
ただし、99%の場合、このようなエラーは、tarファイルに配置しようとしているディレクトリ内にtarファイルを作成していることを意味します。そのため、tarはディレクトリを読み取ろうとすると、ディレクトリのメンバーとしてtarファイルを見つけ、tarファイルへの読み取りと書き込みを開始します。したがって、tarファイルの読み取りを開始してから終了するまでの間にtarファイルを読み取ると、tarファイルが変更されました。
たとえば、次のようなものです。
tar cf ./foo.tar .
間違っていないため、これを「停止」する方法はありません。 tarファイルを作成するときに別の場所に置くか、または--exclude
などを使用してtarファイルを省略します。
これは、tarの終了ステータスが1である場合にそれを無視するためのワンライナーです。 sandeepのスクリプト のようにset +e
の必要はありません。 tar終了ステータスが0または1の場合、このワンライナーは終了ステータス0で戻ります。それ以外の場合、終了ステータス1で戻ります。これは、元の終了ステータス値が sandeepのスクリプト と異なる1と異なる場合は保持されます。
tar -czf sample.tar.gz dir1 dir2 || [[ $? -eq 1 ]]
ファビアンのワンライナーを強化するため。終了ステータス1のみを無視し、それ以外の場合は終了ステータスを保持するとします。
tar -czf sample.tar.gz dir1 dir2 || ( export ret=$?; [[ $ret -eq 1 ]] || exit "$ret" )
これは、sandeepのスクリプトが行うすべてを1行で実行します。
出力に外部ディレクトリを使用するだけで、問題が解決しました。
Sudo tar czf ./../31OCT18.tar.gz ./