편집하다:

편집하다:

쉘 스크립팅을 처음 접했고 서버 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/error.txt모든 오류를 기록하려면 두 파일을 모두 사용하여 로그를 균일하게 유지합니다.네트워크 장애: 여기에 이미지 설명을 입력하세요.

노트:

  1. 출력을 구문 분석하면 안 됩니다.ls
  2. mailx -E 빈 본문을 방지하여 파일이 이동되지 않으면 전송되지 않습니다.
  3. mvmailx는 오류가 발생한 경우 오류가 발생하기 전에 어떤 파일이 이동되었는지 계속 알고 싶기 때문에 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

인수 목록이 너무 긴 경우

#! /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

관련 정보