makefile - seminario - en una propuesta de investigación,los objetivos deben mostrar una relación clara y consistente con:
tar: el archivo ha cambiado a medida que lo leímos (5)
Estoy usando make
y tar
para hacer una copia de seguridad. Al ejecutar makefile, el comando tar muestra que el file changed as we read it
. En este caso,
- el paquete tar está bien cuando aparece la advertencia
- pero detiene el comando tar para la siguiente copia de seguridad
- el archivo que muestra la advertencia, de hecho, no cambia, es realmente extraño que aparezca la advertencia
- los archivos que muestran la advertencia aparecen al azar, quiero decir, cada vez que ejecuto mi archivo MAKE, los archivos que muestran la advertencia son diferentes
-
--ignore-failed-read
no ayuda. Estoy usando tar 1.23 en MinGW - Acabo de cambiar mi computadora a WIN7 de 64 bits. La secuencia de comandos funciona bien en WIN7 antiguo de 32 bits. Pero la versión tar no es tan nueva como la 1.23.
¿Cómo puedo detener la advertencia del tar para detener mi copia de seguridad después de la advertencia?
Edit-2 : podría ser la razón
Como dije anteriormente, el script bash shell funcionó bien en mi vieja computadora. Comparando con la vieja computadora, la versión de msys
es diferente. También lo es la versión del comando tar. En la computadora vieja, tar es 1.13.19 y es 1.23 en la nueva computadora. Copié el antiguo comando tar sin copiar su dependencia msys-1.0.dll a la nueva computadora y lo renombré tar_old. Y también actualicé el comando tar en el script de shell y ejecuté el script. Entonces todo está bien. Entonces, parece que el problema es el comando tar. Estoy seguro de que no hay ningún archivo modificado al tarar. ¿Es un error para el comando tar en la nueva versión? No lo sé.
Editar-1 : agregar más detalles
La copia de seguridad es invocada por un script de shell bash. Escanea el directorio de destino y crea el archivo MAKE e invoca make para usar el comando tar para la copia de seguridad. Seguido es un archivo MAKE típico construido por el script bash shell.
#--------------------------------------------
# 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
Como puede ver, el paquete tar está almacenado en ~ / MS_bak_MSYS / tools / VC / VC_2010.tar.bz2. Ejecuto el script en ~ / qqaa. ~/MS_bak_MSYS
está excluido del comando tar. Entonces, el archivo tar que estoy creando no está dentro de un directorio que estoy tratando de poner en el archivo tar. Es por eso que me pareció extraño que surgiera la advertencia.
Aquí hay una línea para ignorar el estado de salida de tar si es 1. No hay necesidad de set +e
como en el script de sandeep . Si el estado de salida de tar es 0 o 1, este one-liner volverá con el estado de salida 0. De lo contrario, volverá con el estado de salida 1. Esto es diferente del script de sandeep donde se preserva el valor de estado de salida original si es diferente de 1 .
tar -czf sample.tar.gz dir1 dir2 || [[ $? -eq 1 ]]
Aunque es muy tarde pero recientemente tuve el mismo problema.
El problema es porque dir .
está cambiando cuando se crea xyz.tar.gz
después de ejecutar el comando. Hay dos soluciones:
Solución 1: a tar
no le importará si el archivo se crea en cualquier directorio interno .
. Puede haber razones por las cuales no puede crear el archivo fuera del espacio de trabajo. Trabajé a su alrededor creando un directorio temporal para poner el archivo como:
mkdir artefacts
tar -zcvf artefacts/archive.tar.gz --exclude=./artefacts .
echo $?
0
Solución 2: Esta me gusta. crea el archivo de almacenamiento antes de ejecutar tar:
touch archive.tar.gz
tar --exclude=archive.tar.gz -zcvf archive.tar.gz .
echo $?
0
Para mejorar el one-liner de Fabian; digamos que queremos ignorar solo el estado de salida 1, pero para preservar el estado de salida si es cualquier otra cosa:
tar -czf sample.tar.gz dir1 dir2 || ( export ret=$?; [[ $ret -eq 1 ]] || exit "$ret" )
Esto hace todo lo que hace el guión de sandeep, en una línea.
Si quiere ayuda para depurar un problema como este, debe proporcionar la regla make o al menos el comando tar invocado. ¿Cómo podemos ver qué pasa con el comando si no hay ningún comando para ver?
Sin embargo, el 99% del tiempo un error como este significa que está creando el archivo tar dentro de un directorio que está tratando de poner en el archivo tar. Entonces, cuando tar intenta leer el directorio, encuentra el archivo tar como miembro del directorio, comienza a leerlo y lo escribe en el archivo tar, y así entre el momento en que comienza a leer el archivo tar y cuando termina leyendo el archivo tar, el archivo tar ha cambiado.
Entonces, por ejemplo algo como:
tar cf ./foo.tar .
No hay forma de "detener" esto, porque no está mal. Simplemente coloque su archivo tar en otro lugar cuando lo cree, o encuentre otra forma (usando --exclude
o lo que sea) para omitir el archivo tar.
También encuentro los mensajes tar "cambiados a medida que lo leímos". Para mí, este mensaje se produjo cuando estaba haciendo un archivo tar del sistema de archivos Linux en el entorno de compilación bitbake. Este error fue esporádico
Para mí, esto no se debió a la creación de un archivo tar desde el mismo directorio. Supongo que en realidad hay algún archivo sobreescrito o cambiado durante la creación del archivo tar.
El mensaje es una advertencia y aún crea el archivo tar. Todavía podemos suprimir estos mensajes de advertencia configurando la opción
--warning=no-file-changed
( http://www.gnu.org/software/tar/manual/html_section/warnings.html )
Aún el retorno del código de salida por el tar es "1" en el caso del mensaje de advertencia: http://www.gnu.org/software/tar/manual/html_section/Synopsis.html
Entonces, si estamos llamando al archivo tar desde alguna función en scripts, podemos manejar el código de salida de la siguiente manera:
set +e
tar -czf sample.tar.gz dir1 dir2
exitcode=$?
if [ "$exitcode" != "1" ] && [ "$exitcode" != "0" ]; then
exit $exitcode
fi
set -e