【问题标题】:gzip already has gz suffix unchanged in the scriptgzip 在脚本中已经有 gz 后缀不变
【发布时间】:2019-01-16 13:59:27
【问题描述】:

我创建了一个脚本来压缩并将日志文件从一个目录移动到另一个目录以释放空间。这是脚本:

#!/bin/bash

logsDirectory="/test//logs/" 
email="" 
backupDirectory="/test/backup" 
pid="/data/test/scripts/backup.pid"
usage=$(df | grep /data/logs | awk '{ print $2 }') 
space=450000000

getBackup () 
{ 
if [[ ! -e $pid ]] then
            if [[ $usage -le $space ]]
                    then
                    touch $pid
                    find $backupDirectory -mtime +15 -type f  -delete;
                    for i in $(find $logsDirectory -type f -not -path "*/irws/*")
                            do
                                    /sbin/fuser $i > /dev/null 2>&1
                                    if [ $? -ne 0 ]
                                    then
                                            gzip  $i
                                            mv -v $i.gz $backupDirectory
                                    else
                                            continue
                                    fi
                            done
                    [[ ! -z $email ]] && echo "Backup is ready" | mas"Backup" $email
                    rm -f $pid
            fi 
fi 
} 
getBackup

我收到此错误:

gzip: /data/logs/log01.log.gz already has .gz suffix -- unchanged
mv: cannot stat `/data/logs/log01.log.gz': No such file or directory

每次在我的 DEV 和 PROD(CentOS 服务器)环境中运行脚本时,我都会遇到错误。为了分析它,我在笔记本电脑的虚拟机(Ubuntu)中运行了相同的脚本,但没有出现错误。

我的问题:

  1. 如何防止出现此错误?
  2. 我在脚本中做错了什么?

【问题讨论】:

  • 文件/data/logs/log01.log.gz 存在于$logsDirectory 中。 gzip 告诉您该文件已经具有 .gz 扩展名并且不会再次压缩它。然后您尝试将/data/logs/log01.log.gz.gz 移动到备份目录中。那失败了。另外,请考虑使用set -x 运行您的脚本。
  • 只需添加一个步骤进行测试,如果它已经以.gz结尾,则跳过它,或者移动它。
  • 感谢您的解决方案,他们帮助我找到了解决方案。

标签: linux bash scripting gzip


【解决方案1】:

您的脚本包含许多常见的笨拙或低效的反模式。这是一个重构。唯一真正的变化是跳过任何*.gz 文件。

#!/bin/bash

logsDirectory="/test//logs/" 
email="" 
backupDirectory="/test/backup" 
pid="/data/test/scripts/backup.pid"
# Avoid useless use of grep -- awk knows how to match a regex
# Better still run df /data/logs
usage=$(df /data/logs/ | awk '{ print $2 }') 
space=450000000

getBackup () 
{
    # Quote variables
    if [[ ! -e "$pid" ]]; then
        if [[ "$usage" -le "$space" ]]; then
            touch "$pid"
            find "$backupDirectory" -mtime +15 -type f  -delete;
            # Exclude *.gz files
            # This is still not robust against file names with spaces or wildcards in their names
            for i in $(find "$logsDirectory" -type f -not -path "*/irws/*" -not -name '*.gz')
            do
                # Avoid useless use of $?
                if /sbin/fuser "$i" > /dev/null 2>&1
                then
                        gzip  "$i"
                        mv -v "$i.gz" "$backupDirectory"
                # no need for do-nothing else
                fi
            done
            [[ ! -z "$email" ]] &&
            echo "Backup is ready" | mas"Backup" "$email"
            rm -f "$pid"
        fi
    fi
}
getBackup

通过稍微侵入性的重构,find 循环的正确修复可能看起来像

            find "$logsDirectory" -type f \
              -not -path "*/irws/*" -not -name '*.gz' \
              -exec sh -c '
                for i; do
                    if /sbin/fuser "$i" > /dev/null 2>&1
                    then
                        gzip  "$i"
                        mv -v "$i.gz" "$backupDirectory"
                    fi
                done' _ {} +

秘诀在于让find ... -exec + 以完全不涉及将参数暴露给当前shell 的方式将参数传递给sh -c 脚本。

【讨论】:

  • 感谢您的出色解决方案,它运行良好,我仍然是 bash 脚本的新手。愿原力与你同在。
【解决方案2】:

我在脚本中做错了什么?

您的脚本尝试压缩每个文件,但 gzip 命令拒绝已压缩的文件

我怎样才能防止这个错误?

让脚本检查文件是否已压缩,如果对应 (1),则仅 gzip。或者,即使它已经被压缩,您也可以强制重新压缩 (2)。

使用选项号 1):

getBackup () 
{ 
  if [[ ! -e $pid ]] then
    if [[ $usage -le $space ]]
    then
      touch $pid
      find $backupDirectory -mtime +15 -type f  -delete;
      for i in $(find $logsDirectory -type f -not -path "*/irws/*")
      do
        /sbin/fuser $i > /dev/null 2>&1
        if [ $? -ne 0 ]
        then
          if [[ $i =~ \.gz$ ]]
            # File is already zipped
            mv -v $i $backupDirectory
          else
            gzip  $i
            mv -v $i.gz $backupDirectory
          fi
        else
          continue
        fi
      done
      [[ ! -z $email ]] && echo "Backup is ready" | mas"Backup" $email
      rm -f $pid
    fi 
  fi 
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多