Tar: файл изменен, когда мы его читаем
Я использую make
и tar
для резервного копирования. При выполнении make файла команда tar показывает file changed as we read it
. В этом случае
- пакет tar доступен, когда появляется предупреждение
- но он останавливает команду tar для следующей резервной копии
- файл с предупреждением на самом деле не меняется - действительно странно, что предупреждение появляется
- файлы с предупреждением появляются случайным образом, я имею в виду, каждый раз, когда я запускаю свой make файл, файлы с предупреждением различаются.
-
--ignore-failed-read
не помогает. Я использую tar 1.23 в MinGW
- Я просто поменял свой компьютер на WIN7 64 бит. script хорошо работает в старой версии WIN7 32 бит. Но версия tar не такая новая, как 1.23.
Как я могу остановить предупреждение tar, чтобы остановить резервное копирование после предупреждения?
Изменить-2: это может быть причина
Как я уже говорил выше, оболочка bash script хорошо работала на моем старом компьютере. Сравнивая со старым компьютером, версия msys
отличается. Так же и версия tar-команды. На старом компьютере tar равен 1,13.19, а на новом компьютере - 1,23. Я скопировал старую команду tar без копирования ее зависимости msys-1.0.dll на новый компьютер и переименовал ее в tar_old. И я также обновил команду tar в оболочке script и запустил script. Тогда все в порядке. Таким образом, казалось, что проблема заключается в команде tar. Я уверен, что ни один файл не изменен при тарировании. Это ошибка для команды tar в новой версии? Я не знаю.
Изменить-1: добавить дополнительные сведения
Резервная копия вызывается оболочкой bash script. Он сканирует целевой каталог и создает make файл, а затем вызывает make для использования tar-команды для резервного копирования. Далее следует типичный make файл, созданный оболочкой bash script.
#--------------------------------------------
# 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) "[email protected]" --ignore-failed-read /c/$(WIN_PRG_DIR)/VC/Framework
$(VC_2010): $(WIN_C_DIR)/$(WIN_PRG_DIR)/VC/VS2010/*
@$(PACK_TOOL) $(PACK_OPTION) "[email protected]" --ignore-failed-read /c/$(WIN_PRG_DIR)/VC/VS2010
Как вы можете видеть, пакет tar хранится в ~/MS_bak_MSYS/tools/VC/VC_2010.tar.bz2. Я запускаю script в ~/qqaa. ~/MS_bak_MSYS
исключается из команды tar. Таким образом, tar файл, который я создаю, не находится внутри каталога, который я пытаюсь поместить в файл tar. Вот почему мне было странно, что предупреждение появилось.
Ответы
Ответ 1
Я также сталкиваюсь с сообщениями tar, "измененными по мере их чтения". Для меня это сообщение произошло, когда я делал tar файл файловой системы Linux в среде сборки bitbake. Эта ошибка была спорадической.
Для меня это произошло не из-за создания 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
Ответ 2
Если вам нужна помощь в отладке такой проблемы, вам необходимо предоставить правило make или, по крайней мере, выписанную команду tar. Как мы можем увидеть, что не так с командой, если нет команды для просмотра?
Однако в 99% случаев такая ошибка означает, что вы создаете файл tar внутри каталога, который вы пытаетесь поместить в файл tar. Итак, когда tar пытается прочитать каталог, он находит файл tar в качестве члена каталога, начинает его читать и записывает в tar файл, и поэтому между временем, когда он начинает читать tar файл и когда он заканчивается чтение tar файла, tar файл был изменен.
Итак, например, что-то вроде:
tar cf ./foo.tar .
Невозможно "остановить" это, потому что это не так. Просто поместите файл tar в другое место при его создании или найдите другой способ (используя --exclude
или что-то еще), чтобы опустить tar файл.
Ответ 3
Хотя его очень поздно, но у меня недавно была такая же проблема.
Проблема связана с тем, что dir .
изменяется при создании xyz.tar.gz
после запуска команды. Существует два решения:
Решение 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
Ответ 4
Вот один лайнер для игнорирования статуса выхода tar, если он равен 1. Нет необходимости set +e
, как в sandeep script. Если статус выхода tar равен 0 или 1, этот однострочный лайнер вернется с статусом выхода 0. В противном случае он вернется с статусом выхода 1. Это отличается от sandeep script, где исходное значение статуса выхода сохраняется, если оно отличается от 1.
tar -czf sample.tar.gz dir1 dir2 || [[ $? -eq 1 ]]