编辑:

编辑:

对 shell 脚本相当陌生,想要编写脚本来检查服务器 10.xx.xx.xx.300上是否存在任何文件扩展名。/exports/files如果*.300存在,将文件移至/exports/files/arch并发送电子邮件至[email protected]。如果*.300没有找到则不执行任何操作。

我尝试了以下建议:

#! /bin/bash

    for FILE in `ls /exports/files/*.300`
    do
       mv $FILE /exports/files/arch
       echo "$FILE moved" | mailx -s $FILE moved [email protected] 
    done

当没有文件时,它会出错并显示ls: cannot access /exports/files/*.300: No such file or directory.有什么办法可以抑制这种情况吗...

答案1

[更新]

#!/usr/bin/env bash
shopt -s nullglob #to make `("$src_dir"*.300)` works
src_dir="/exports/files/" #don't forget trailing slash /
dest_dir="/exports/files/arch/" #don't forget trailing slash /
err_f="/tmp/error.txt"
mv_f="/tmp/moved.log" #record moved file in case network down
email="[email protected]"
touch "$err_f" #bcoz we use >> apppend
touch "$mv_f" #bcoz we use tee -a append
if [ ! -d "$src_dir" ]; then echo|mailx -s "Error: directory $src_dir not exist" "$email" 2>>"$err_f"; exit 1; fi
if [ ! -d "$dest_dir" ]; then echo|mailx -s "Error: directory $dest_dir not exist" "$email" 2>>"$err_f"; exit 1; fi
{
f=("$src_dir"*.300)
for ((i=0; i < ${#f[@]}; i+=1)); do
        mv -f "${f[i]}" "$dest_dir"  2>>"$err_f"; #-f do not prompt
        if [ $? -eq 0 ]; then
                if [ "$i" -eq 0 ]; then echo "$(date +"%Y-%m-%d %H:%M:%S")"; echo "The following files has been moved from $src_dir to $dest_dir"; echo; fi
                echo "$((i+1))." "$(basename "${f[i]}")" 'moved'; echo;
        else
                 echo| mailx -s "Error:  $(<"$err_f")" "$email" 2>>"$err_f"; break
        fi
done
} | tee -a "$mv_f" | mailx -E -s "The following files has been moved" "$email" 2>>"$err_f"

邮件收件箱截图示例:

收到邮件时mv出错: 在此输入图像描述

成功后收到邮件mv在此输入图像描述

/tmp/moved.log记录文件移动和/tmp/错误.txt要记录所有错误,两个文件都用于保持日志均匀网络故障: 在此输入图像描述

笔记:

  1. 你不应该解析的输出ls
  2. mailx -E 以避免空正文,因此如果没有移动文件,则不会发送
  3. mailx只有一个如果mv遇到错误,通过使用break提前中断而不是exit 1因为我们仍然想知道在错误发生之前哪个文件已被移动。
  4. cmd; if [ $? -eq 0 ]隐式比较的优点if cmd是您可以轻松地将其修改为可能需要不同返回代码的其他命令。
  5. 您应该手动删除 /tmp/error.txt 和 /tmp/moved.log ,它们会不时附加。

参考:

  1. http://mywiki.wooledge.org/ParsingLs
  2. http://lcorg.blogspot.com/2009/04/tip-redirecting-multiple-command.html
  3. https://serverfault.com/questions/349989/sending-mail-from-command-line-if-body-not-empty

  4. https://stackoverflow.com/questions/16036763/get-formatted-date-from-timestamp-with-rounded-milliseconds-bash-shell-script

答案2

像这样的事情应该可以解决问题。如果您需要远程访问服务器,请使用 ssh 证书并使用 ssh 执行此脚本。

    #! /bin/bash

    for FILE in `ls /exports/files/*.300`
    do
       mv $FILE /exports/files/arch
       echo "$FILE moved" | mailx -s $FILE moved [email protected] 
    done

答案3

只是为了好玩

 #! /bin/bash

ls /exports/files/*.300 | while read FILE 
do
   if mv $FILE /exports/files/arch
   then echo "$FILE moved" 
fi
done | mailx -s files moved [email protected] 

将为您提供一封包含所有移动文件的邮件,并跳过错误。

只有 3 层管道。

编辑:

文件很少:

#! /bin/bash
if ls /exports/files/*.300 > /dev/null 2>&1
then 

   ls /exports/files/*.300 | awk '{printf "%s moved\n",$0 }' | mailx -s files moved [email protected]
   mv /exports/files/*.300 /exports/files/arch

 else 
   echo no .300 file found | mailx -s no .300 files moved [email protected]

fi

如果 arg 列表太长

#! /bin/bash
if ls /exports/files/*.300 > /dev/null 2>&1
then 
   ls /exports/files/*.300 | while read FILE 
   do
      if mv $FILE /exports/files/arch
      then echo "$FILE moved" 
      fi
   done | mailx -s files moved [email protected] 
fi

相关内容