조건이 실패할 때 메시지 본문을 실패로 보내는 방법은 무엇입니까?

조건이 실패할 때 메시지 본문을 실패로 보내는 방법은 무엇입니까?

S3 버킷이 있습니다...파일이 매일 업로드되고 메일로 보내야 합니다...메일은 잘 작동하지만 파일이 업로드되지 않으면 메일 본문이 빈 상태로 전송됩니다...어떻게 할 수 있나요? 텍스트에 "실패"라고 입력하시나요... 조건이 실패했을 때

위 코드는 파일이 업로드되면 매일 파일을 메일로 보내주지만...파일이 업로드되지 않으면 빈 메일 본문으로 보내지는데...파일이 업로드되지 않으면 "실패"로 메일을 보내야 합니다. , 어떻게 해야 할까요? 루프에서 시도했지만 작동하지 않았습니다. 어떻게 두 개의 s3 버킷 콘텐츠를 동일한 메일로 보낼 수 있습니까?

답변1

간단하게 유지하려면 다음 단계를 수행하세요.

  1. 메시지를 임시 파일에 저장합니다.
  2. 메시지가 비어 있는지 확인하세요.
  3. 적절한 조치를 취하십시오.
  4. 임시 파일을 삭제합니다.
#!/bin/sh

tmpfile=$(mktemp)

aws s3 ls "s3://project/js/Historical/$(date +'%Y/%m_%B/')" |
grep -Fe "$DATE" |
sort -rh |
head -n 2 |
awk -v OFS='\t' '{ print $1, $2, $4 }' >"$tmpfile"

if [ -s "$tmpfile" ]; then
    mail -s 's3' [email protected] <"$tmpfile"
else
    mail -s 's3 (failed)' [email protected] <<MESSAGE_END
Something failed.
You should check it.
MESSAGE_END
fi

rm -f "$tmpfile"

또한 다른 변경 사항도 확인하세요.

  1. URI를 올바르게 인용하십시오 s3:(명령 대체가 포함되어 있음).
  2. date세 번 호출하는 대신 한 번 호출합니다 (그렇지 않으면 특정 시간에 실행하면 문제가 발생할 수 있음).
  3. -Fe알 수 없는 문자열을 일치시키려면 with를 사용하세요 grep.
  4. awk스크립트를 올바르게 인용 하고 OFS출력 필드 구분 기호를 탭으로 설정하는 데 사용합니다(가독성 향상을 위해).

반복적인 코드 작성을 좋아하지 않는 분들을 위해 ("건조" 원리):

#!/bin/sh

tmpfile=$(mktemp)

aws s3 ls "s3://project/js/Historical/$(date +'%Y/%m_%B/')" |
grep -Fe "$DATE" |
sort -rh |
head -n 2 |
awk -v OFS='\t' '{ print $1, $2, $4 }' >"$tmpfile"

subject='s3'
if [ ! -s "$tmpfile" ]; then
    subject="$subject (failed)"
    cat >"$tmpfile" <<MESSAGE_END
Something failed.
You should check it.
MESSAGE_END
fi

mail -s "$subject" [email protected] <"$tmpfile"
rm -f "$tmpfile"

존재하다논평aws s3 ls, 두 통화를 모두 처리할 수 있는 솔루션을 찾고 있습니다.

다음 코드는 버킷 URI 배열을 반복하여 각 파일 목록을 별도의 임시 파일에 배치하고 bash파이프라인이 빈 결과를 생성할 때 사용자 지정 메시지를 삽입합니다. aws마지막으로 모든 메시지는 삭제되기 전에 연결되어 전송됩니다.

#!/bin/bash

bucket=( "s3://project/js/Historical/$(date +'%Y/%m_%B/')" 
         "s3://some-other-path" )

msgfile=()
for uri in "${bucket[@]}"; do
    tmpfile=$(mktemp)

    msgfile+=( "$tmpfile" )

    aws s3 ls "$uri" |
    grep -Fe "$DATE" |
    sort -rh |
    head -n 2 |
    awk -v OFS='\t' '{ print $1, $2, $4 }' >"$tmpfile"

    if [ ! -s "$tmpfile" ]; then
        cat >"$tmpfile" <<MESSAGE_END
Something failed for bucket "$uri".
You should check it.
MESSAGE_END
    fi
done

cat "${msgfile[@]}" | 
mail -s 's3 file listings' [email protected]

rm -f "${msgfile[@]}"

(테스트되지 않음)

답변2

grep나는 그 명령이 당신의 조건을 구현하려는 곳이라고 믿습니다 . 이를 달성하려면 다음 구문을 사용할 수 있습니다.

grep ${DATE} && : || echo "Fail"

이는 표준 if..else..fi 문의 단축 버전인 bash 구성입니다.

여기서의 아이디어는 grep일치하는 항목이 발견되면 아무 작업도 수행하지 않는다는 것입니다( :연산자 사용). 이렇게 하면 grep의 출력이 파이프라인의 다음 명령으로 흐를 수 있습니다.

표준 입력에서 일치하는 항목을 찾을 수 없으면 grep"Fail" 문자열이 출력됩니다.

전체 파이프라인은 다음과 같아야 합니다.

aws s3 ls s3://project/js/Historical/$(date +%Y)/$(date +%m)_$(date +%B/) | grep ${DATE} && : || echo "Fail" | sort -rh | head -n 2 | awk {' print $1"\t"$2"\t"$4'} | mail -s "s3" "[email protected]"

원하는 경우 출력 문자열을 변경할 수 있지만 제대로 작동하는지 확인하려면 파이프라인( sort, head및 ) 에서 다음 명령을 사용해야 합니다 .awk

관련 정보