나는 "빠른" 스크립트를 작성한 다음 메일 스위치(에코에서 파이프되는 구문)를 끄기 위해 "--nomail" 옵션을 추가하는 것을 고려했습니다.
나는 그것이 쉬울 것이라고 생각했지만 근본적으로 원본 스크립트를 잘 구성하지 않았기 때문에 이 "옵션"이 나를 죽였습니다.
Bash의 새로운 기능입니다... 감사합니다!
내 멋진 작업 스크립트! :
## Current threshold value setting
THRESHOLD="80"
## Input Files and Mailx
LOCATIONS="fsIn.txt" ## Edit "fsIn.txt" to add or change filesystems
TOLIST="$(cat toList.txt | tr -s '\n' ' ' )" ## Sets who receives email if an error condition exists
REPLYTO="$(cat replyTo.txt | tr -s '\n' ' ' )" ## sets the reply to email addresses
FROM=”SCRIPT TEAM" ## Sets the "from" address on error emails
SUBJECT="$HOST: ! STORAGE LEVEL MET OR EXCEEDED !" ## Sets the subject line
############
for i in $(cat $LOCATIONS)
do
## Main df pipeline to return usage percentage
CAP=$(df -PH --no-sync "$i" | awk 'NR>1'| awk {'print $5'} | sed 's/.$//')
for i in $(cat $LOCATIONS) #Several different file system locations are ‘catted’ in here . E.g. /dev
do
## Main df pipeline to return usage percentage to stdout and piped to mailx
CAP=$(df -PH --no-sync "$i" | awk 'NR>1'| awk {'print $5'} | sed 's/.$//')
if [ $CAP -ge $THRESHOLD ]
then
(echo
echo "---------- CAPACITY TEST FAILED ---------- "
echo -n " SYSTEM NAME: " ; uname -n
echo -n " USER DETAIL: " ; whoami
echo " TEST AREA: $i "
echo " USED SPACE: $CAP% "
echo " THRESHOLD: $THRESHOLD% "
echo " !!!!!! THRESHOLD EXCEEDED !!!!!! ") | tee >(mailx -s "$SUBJECT" -r "$FROM" -S replyto="$REPLYTO" "$TOLIST")
echo
else
echo
echo "++++++++++ CAPACITY TEST PASSED ++++++++++ "
echo " TEST AREA: $i "
echo " USED SPACE: $CAP% "
echo " THRESHOLD: $THRESHOLD% "
echo " !!! SUCCESS SUCCESS SUCCESS SUCCESS !!! "
echo
fi
done
exit 0
이것은 아주 잘 작동합니다! 하지만 --nomail 옵션을 포함하도록 재구성하는 방법을 모르겠습니다. "사례"가 신중한 것 같지만 여기서는 길을 잃었습니다.
어떤 아이디어가 있나요?
매우 감사합니다!
답변1
간단한 대답은 두 가지입니다.
send_email
to 와 같은 플래그를 설정하고true
이메일 억제 매개변수가 있는 경우 이를 설정 해제하거나 false로 설정합니다.- 출력이 될 변수나 임시 파일을 조합한 다음 실제 이메일 전송을 함수 호출에 전달하여 미리 이메일을 작성합니다.
예를 들어:
send_email="true"
handle_email() {
echo "$email_body" | mailx -s "$subject" -r "$from" -S replyto="$replyto" ${recipients[@]}
}
[...]
if [[ "--nomail" == "$1" ]]; then
send_email=false
fi
[...]
if [[ true == "$send_email ]]; then
handle_email
fi
답변2
고쳐 쓰다
나는 돌아가서 귀하의 질문 전체를 읽었으며 원래 귀하가 요청한 질문과 약간 다른 질문에 대답했다는 것을 깨달았습니다. 그래서 여기에 있습니다:
당신의 구조는 훌륭합니다. 스크립트 시작 부분에서 명령 옵션을 구문 분석합니다.
case
예, 문을 사용 하여 확인할 수 있습니다$1
(아래 원래 답변 참조). 하지만 한 가지 옵션만 계획하는 경우 단일 테스트를 쉽게 수행할 수 있습니다(아래 원래 답변 참조).case
여러 가지 가능한 옵션이 포함된 명령문을 사용하려면 해당 명령을while
명령 줄의 다음 단어/옵션으로 대체합니다 .while "$1" ; do case ... esac; shift; done
shift
$1
원래 답변
이 문제를 해결하는 방법에는 여러 가지가 있습니다. 이것이 유일한 옵션이거나 몇 가지 옵션만 있는 경우 직접 수동으로 구문 분석하는 것을 고려할 수 있습니다. 쉘 언어에서는 쉘 명령 뒤에 오는 모든 단어를 쉘이라고 합니다.매개변수, 그리고 각각은위치 매개변수, 양식은 1 $n
부터 시작됩니다 n
. 따라서 테스트를 수행하여 문제가 발생하는지 확인 [[ $1 == "--nomail" ]]
하고 그에 따라 조치를 취할 수 있습니다. 이는 옵션이 하나만 있는 간단하고 간단한 방법입니다.
getopts
옵션이 많은 더 복잡한 셸 스크립트의 경우 특정 형태의 명령을 활용하여 옵션을 구문 분석 해야 할 수도 있습니다 . 셸에는 내장 버전이 bash
포함되어 있으며 명령줄에 then(기본 호출기가 설정된 경우)을 입력하여 자세한 내용을 알아볼 수 있습니다 .getopts
man bash
less
/^ *getopt
답변3
다른 답변에서는 이미 명령줄 옵션을 사용하는 방법을 언급했습니다(즉, "$1"
직접 확인하거나 사용 getopts
). 내 대답은 --nomail
스크립트를 처음부터 다시 작성할 필요 없이 옵션을 사용하도록 스크립트를 빠르게 수정하는 방법입니다 . 쉘 스크립팅 기술과 지식의 점진적인 향상을 활용하려면 장기적으로 이 작업을 수행해야 합니다.
가장 확실한 방법은 변수나 임시 파일을 사용하여 인쇄하려는 출력을 저장하거나 인쇄하여 메일로 보낸 다음 매번 이를 어떻게 처리할지 선택하는 것입니다.
덜 분명한 방법은 파이프를 표준 입력 인지 아니면 그냥 입력인지 tee >(mailx ...)
를 결정하는 함수 호출에 대한 파이프로 바꾸는 것입니다 . 이 접근 방식을 사용하면 출력을 저장할 필요가 없으며 출력을 파이프하고 함수가 처리하도록 두면 됩니다. 나머지 코드는 알거나 신경 쓸 필요가 없습니다(그리고 가장 중요한 것은 처리하기 위해 작성할 필요가 없습니다). 두 경우 모두).tee
mailx
cat
그게 다야 ...
먼저 스크립트 시작 부분 근처에 다음과 같은 코드를 추가합니다.
# set the default, i.e. to send mail.
send_email=1
# Very basic option processing. Using getopts would be better.
[ "$1" == "--nomail" ] && send_email=''
myoutput() {
if [ "$send_email" ] ; then
# print stdin to stdout AND mail it
tee <(mailx -s "$SUBJECT" -r "$FROM" -S replyto="$REPLYTO" "$TOLIST")
else
# only print stdin to stdout. no mail.
cat
fi
}
둘째, | tee ...
루프 내에서 교체하여 여기에 정의된 함수를 사용합니다.for
| myoutput
( myoutput
형편없는 함수 이름입니다. 이름을 바꾸 cat_or_mail
거나 가장 이해하기 쉬운 이름으로 바꾸세요.)
이상적으로 함수는 전역 변수에 의존하기보다는 매개변수를 허용해야 하며 다음과 같이 작성되어야 합니다.
myoutput() {
local send_email SUBJECT FROM REPYLTO TOLIST
# more of the primitive option handling. getopts can and should be used
# inside a function too.
send_email="$1"
SUBJECT="$2"
FROM="$3"
REPLYTO="$4"
TOLIST="$5"
# add code here to check if those variables contain valid values.
# print warnings and/or abort and/or set appropriate defaults if they don't.
if [ "$send_email" ] ; then
# print stdin to stdout AND mail it
tee <(mailx -s "$SUBJECT" -r "$FROM" -S replyto="$REPLYTO" "$TOLIST")
else
# only print stdin to stdout. no mail.
cat
fi
}
그리고 전화해... | myoutput "$send_email" "$SUBJECT" "$FROM" "$REPLYTO" "$TOLIST"
이렇게 하면 전역 변수를 미리 설정할 필요 없이 함수를 재사용할 수 있습니다. 필요한 값으로 호출하기만 하면 됩니다.