쉘 스크립팅을 처음 접했고 서버 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모든 오류를 기록하려면 두 파일을 모두 사용하여 로그를 균일하게 유지합니다.네트워크 장애:
노트:
- 출력을 구문 분석하면 안 됩니다.
ls
- mailx -E 빈 본문을 방지하여 파일이 이동되지 않으면 전송되지 않습니다.
mv
mailx는 오류가 발생한 경우 오류가 발생하기 전에 어떤 파일이 이동되었는지 계속 알고 싶기 때문에break
대신 조기 중단을 사용하여 하나만 갖습니다 .exit 1
cmd; if [ $? -eq 0 ]
암시적 비교의 장점은if cmd
다른 반환 코드가 필요할 수 있는 다른 명령에 대해 쉽게 수정할 수 있다는 것입니다.- 수시로 첨부되는 /tmp/error.txt, /tmp/moved.log를 수동으로 삭제하셔야 합니다.
인용하다:
답변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