if
명령문에 도달할 때까지 모든 명령을 실행하는 스크립트가 있습니다 .
스크립트:
#!/bin/bash
######VARIABLES#######
#grep return value
gret=$?
######LOGIC#######
cd /home/logs
echo "Enter filename: "
read filenamex
echo "filename : ${filenamex}"
grep ${filenamex} log.dat | grep "End receiving ftp file:"
echo $?
if [ {gret} -ne 0 ]; then
echo "{filenamex} cannot be found in the recent logs. We will now check the old logs."
sleep 3
grep ${filenamex} log.dat* | grep "End receiving ftp file:"
fi
grep
필요한 값을 얻을 수 없는 경우 스크립트가 if
명령문을 실행할 수 있도록 스크립트를 실행하는 데 도움을 줄 수 있는 사람이 있습니까?
답변1
$
코드의 주요 문제는 테스트에서 누락된 것( {gret}
이어야 하거나 ${gret}
아직 더 나은 것이어야 함 )과 종료 상태를 변수에 "$gret"
할당하지 않는다는 것입니다 ( 아래 설명과 같이 with를 직접 사용하는 경우에는 실제로 필요하지 않음). .grep
gret
grep
if
if
명령문의 종료 상태를 명령문에서 직접 사용할 수 있습니다. 아래 코드에서는 대화형으로 요청하는 대신 파일 이름을 명령줄 인수로 요구합니다.
#!/bin/sh
if [ -z "$1" ]; then
echo 'Expected to get a filename as argument'
exit 1
fi >&2
if ! grep -Fe "$1" /home/logs/log.dat | grep -F 'End receiving ftp file:'
then
echo 'Checking older logs...' >&2
grep -Fe "$1" /home/logs/log.dat?* | grep -F 'End receiving ftp file:'
fi
위의 코드는 패턴을 정규식으로 해석하는 것을 방지하고 패턴이 대시로 시작하는 경우 옵션 세트로 착각하는 것을 방지하기 위해 -F
with를 사용합니다. 주어진 문자열을 정규식으로 사용하려면 각 파이프의 첫 번째 문자열에서 해당 문자열을 제거하세요.grep
-e
-F
grep
grep
파일 이름 와일드카드 패턴은 실제 이름 자체가 아니라 로 시작하는 이름과 /home/logs/log.dat?*
일치합니다 . 이름의 초기 접두사 뒤에 최소한 하나의 추가 문자를 요구함으로써 이를 수행합니다 ./home/logs
log.dat
log.dat
log.dat
특정 기능을 사용하지 않기 때문에 스크립트를 sh
스크립트 로 바꿨습니다.bash
거의 동일한 grep
파이프라인을 두 번 반복하지 않도록 위의 코드를 리팩터링합니다.
#!/bin/sh
if [ -z "$1" ]; then
echo 'Expected to get a filename as argument'
exit 1
fi >&2
do_grep () {
pattern=$1; shift
grep -Fe "$pattern" -- "$@" |
grep -F 'End receiving ftp file:'
}
if ! do_grep "$1" /home/logs/log.dat; then
echo 'Checking older logs...' >&2
do_grep "$1" /home/logs/log.dat?*
fi