아래 코드가 명확하다는 것을 볼 수 있듯이 내부 루프는 작동하는 것처럼 보이지만 다른 루프 아래에 중첩되면 작동하지 않습니다. ( no idea why
)
아이디어는 a
b
while1을 사용하여 변수를 반복하고 이를 while2에 제공하는 것입니다. while2는 Case 문을 실행하기 위해 log_file에 한 줄이 나타날 때까지 기다립니다.
실제 프로세스에서는 작동하지 않습니다. 실제 log_file입니다.
#!/bin/bash
bi_log='/var/log/process/process.log'
bi_conf='/etc/process/process.conf'
cat input_file | while
read a b
do
while IFS= read -r line; do
case $line in
"Processing Data ended*"* ) echo "Found" &&
echo $a $b >> $bi_conf
;;
esac
sleep 1
break
done < <(tail -n0 -f $bi_log)
done
내부 루프가 제대로 작동하는 것처럼 보이지만 외부 루프 아래에 중첩하면 문제가 발생할 수 있습니다. 변수 a
& b
는 파일에 반영되지 않습니다.
답변1
스크립트에는 몇 가지 문제가 있습니다. 첫 번째는 tail -n0 -f $bi_log
종료되지 않으므로 외부 루프가 두 번째 줄에 도달하지 않는다는 것입니다 input_file
.
다음과 같은 것을 더 시도해 보세요.
while read -r a b ; do
tail -n0 -f "$bi_log" |
awk -v a="$a" -v b="$b" \
'/Processing Data ended/ {
print "found" > /dev/stderr;
print a, b ;
exit
}' >> "$bi_conf"
done < input_file
이 awk 스크립트는 출력을 인쇄하고 일치하는 항목을 찾으면 즉시 종료됩니다. tail -n0 -f
루프가 다음 줄로 이동하는 동안 파이프와 셸이 종료됩니다 input_file
(그리고 새 tail | awk
파이프가 시작됩니다).
그런데, 이것이 -v a="$a" -v b="$b"
쉘 변수를 전달하는 것 $a
입니다.앗변수 a
와 쉘 변수는 $b
awk 변수로 변환됩니다 b
. 또는 export a b
쉘에서 및 를 사용하여(하위 프로세스에 표시되는 환경으로 내보내지도록) awk 에서 사용할 수 있습니다 ENVIRON["a"]
.ENVIRON["b"]
input_file
a
및 변수에 대해 더 많이 알고 있다면 아마도 b
모든 작업을 에서 수행할 수 있을 것입니다 awk
. 또는 perl
.
또는 bash
just 및 를 사용하여 이 작업을 수행 할 수 있습니다 grep
. 예를 들어
while read -r a b ; do
tail -n0 -f "$bi_log" | grep -q -m 1 'Processing Data ended'
echo "Found"
echo "$a $b" >> "$bi_conf"
done < input_file
이 -m NUM
옵션은 일치 후 종료하도록 grep에 지시합니다 NUM
(이 경우 NUM=1). 이 -q
옵션은 grep에게 조용히 하라고 지시합니다. 즉, 출력을 생성하지 않고 종료 코드만 반환합니다(성공의 경우 0, 실패의 경우 1... 그러나 grep의 입력은 tail -f
일치하는 항목을 찾을 때까지 영원히 계속 읽습니다).
추신: 일반적으로 쉘에서 while/read 루프를 작성하는 경우, 멈추고 "이 작업을 awk/perl/python/anything-but-shell에서 해야 하나?"라고 생각해야 합니다. 그런 다음 좀 더 적절한 언어로 작성해 보세요.
쉘은 텍스트 및 데이터 처리 도구의 실행을 조정하는 데 이상적입니다. 핸들링 자체가 형편없습니다.
바라보다쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?자세한 내용과 예시를 알아보세요.