여러 UDP 스트림을 모니터링하고 이를 실행 가능한 데이터로 변환하기 위해 bash 스크립트를 설정했습니다. 내 문제는 스트림 캡처가 실행 중인지 주기적으로 확인하고 그렇지 않으면 다시 시작하도록 스크립트를 설정해야 한다는 것입니다.
문제는 각 스트림 캡처에 대해 새로운 프로세스 이름이나 ID를 생성하고 실행 중인지 확인하는 것입니다.
이것은 내가 가지고 있는 것의 희석된 버전입니다. 내가 올바른 길을 가고 있는지 누군가가 말해 줄 수 있기를 바랍니다.
Subscriber () {
processName="$1$2$4";
echo "$processName";
pgrep $processName;
if [[ $? -ne 0 ]] ; then
echo "Subcription for $1 with IP $2 not found, restarting." ;
while read -re -t 43200 doc; do
<Code to analyze stream>
done < <(bash -c "exec -a $processName <Commands to capture stream as JSON doc>")
else
echo "Subcription for $1 wtih IP $2 found to be running, skipping." ;
fi
}
while read line; do
Subscriber $line;
done < $flatFile
이상적으로는 exec -a 다음에 나열된 전체 명령 문자열의 프로세스 ID나 이름을 가져오고 싶지만 현재는 다소 작동하는 것처럼 보이는 첫 번째 명령만 허용하지만 이것이 내가 원하는 작업을 수행할 것이라고 믿지 않습니다. 하다.
flatFile 참조는 내가 모니터링하고 있는 수백 개의 스트림을 나열하는 동적으로 업데이트되는 플랫 파일입니다.
답변1
argv[0]
Linux의 프로세스 이름은 적어도 프로세스가 명령을 실행할 때마다 변경되지만 bash가 전달하도록 허용하는 것이 아니라 실행 중인 파일의 기본 이름으로 변경됩니다 exec -a
.
pgrep
인수 목록(공백으로 연결됨)의 옵션을 일치시키는 것이 가능 하지만 for 와 -f
마찬가지로 정규식 일치가 수행되므로 원하는 것과 일치하도록 정규식을 구성해야 합니다 .grep
pgrep
r
e
argv[0]
또는 전달된 이름에 exec -a
정규식 문자( .
IPv4 주소에 흔히 사용되는 문자 포함)가 포함되지 않도록 할 수 있습니다.
Subscriber () {
process_arg0="$1$2$4"
# change all regex operators and space to _
process_arg0="${process_arg0//[][ .\\+?\$^()*{\}]/_}"
printf>&2 '%s\n' "$process_arg0"
if ! LC_ALL=C pgrep -f "^$process_arg0( |\$)"; then
printf>&2 '%s\n' "Subscription for $1 with IP $2 not found, restarting."
while IFS= read -r -t 43200 doc; do
<Code to analyze stream>
done < <(
exec -a "$process_arg0" <Commands to capture stream as JSON doc>
)
else
printf>&2 '%s\n' "Subscription for $1 with IP $2 found to be running, skipping."
fi
}
echo
(따옴표 없는 따옴표, 의 사용 , 에 대한 의미 없는 -e
옵션 , 인터프리터 코드에 포함된 변수 데이터 read
누락 과 같은 기타 눈에 띄는 오류도 제거했습니다 .)IFS=
read
그럼에도 불구하고 이름이나 매개변수 목록으로 프로세스를 일치시키는 것은 매우 취약하고 위험합니다. 모든 프로세스가 원하는 이름이나 매개변수 목록을 스스로 할당할 수 있고 여기서 사용된 접근 방식은 경쟁 조건을 도입하기 때문입니다. 초기화 시스템( systemd
, 및 co ) 또는 , , upstart
와 같은 전용 도구와 같은 적절한 프로세스 감독자/감독자를 사용하는 것이 더 적절할 수 있습니다 .runit
daemontools
supervisor
start-stop-daemon