타임 아웃으로 쉘에서 FIFO/파이프에 쓰기
-
05-07-2019 - |
문제
이름이 지정된 파이프에 대해 이야기하는 쉘 프로그램이 있습니다. 독자는 파이프가 시작될 때 파이프를 생성하고 종료 할 때 제거합니다.
때때로, 작가는 독자가 읽기를 멈추는 시간과 파이프를 제거하는 시간 사이에 파이프에 편지를 쓰려고 시도합니다.
reader: while condition; do read data <$PIPE; do_stuff; done
writer: echo $data >>$PIPE
reader: rm $PIPE
이런 일이 발생하면 작가는 글을 쓰기 위해 파이프를 열려고 영원히 매달릴 것입니다.
a 깨끗한 시간 초과를 제공하는 방법으로 수동으로 죽을 때까지 매달리지 않도록? 나는 내가 할 수 있다는 것을 안다
#!/bin/sh
# timed_write <timeout> <file> <args>
# like "echo <args> >> <file>" with a timeout
TIMEOUT=$1
shift;
FILENAME=$1
shift;
PID=$$
(X=0; # don't do "sleep $TIMEOUT", the "kill %1" doesn't kill the sleep
while [ "$X" -lt "$TIMEOUT" ];
do sleep 1; X=$(expr $X + 1);
done; kill $PID) &
echo "$@" >>$FILENAME
kill %1
그러나 이것은 일종의 icky입니다. C 컴파일러를 분해하지 않고 더 깨끗하게 수행하기위한 쉘 내장 또는 명령이 있습니까?
해결책 3
이 프로그램 쌍은 명명 된 파이프 대신 UNIX 도메인 소켓을 사용하여 PERL에 다시 작성된 후 훨씬 더 잘 작동합니다. 이 질문의 특정 문제는 한쪽 끝이 사망 할 때 연결이 교수형 대신 사라지기 때문에 완전히 사라졌습니다.
다른 팁
이것을 다루는 유닉스 "표준"방법은 사용하는 것입니다. 예상하다, 시간이 지남에 따라 제공되는 예제 : 주어진 시간 동안 만 프로그램을 실행합니다.
기대는 스크립팅을 위해 놀라운 일을 할 수 있습니다. TCL을 좋아하지 않는다면 a가 있습니다 파이썬은 기대합니다 모듈도.
이 질문은 주기적으로 나옵니다 (검색으로 찾을 수는 없지만). 타임 아웃 명령으로 사용하기 위해 두 개의 쉘 스크립트를 작성했습니다. 하나는 표준 입력을 읽는 것과 표준 입력을 읽지 않는 것들을위한 것입니다. 이것은 악취가 났고 나는 C 프로그램을 작성하는 것을 의미했지만 아직 그것에 대해서는 얻지 못했습니다. 나는 확실히 a를 쓰는 것이 좋습니다 timeout
C로 한 번에 명령하십시오. 그러나 다음과 같은 두 개의 쉘 스크립트가 더 간단합니다. 명령이 표준 입력을 읽으면 매달려 있습니다.
#!/bin/ksh
# our watchdog timeout in seconds
maxseconds="$1"
shift
case $# in
0) echo "Usage: `basename $0` <seconds> <command> [arg ...]" 1>&2 ;;
esac
"$@" &
waitforpid=$!
{
sleep $maxseconds
echo "TIMED OUT: $@" 1>&2
2>/dev/null kill -0 $waitforpid && kill -15 $waitforpid
} &
killerpid=$!
>>/dev/null 2>&1 wait $waitforpid
# this is the exit value we care about, so save it and use it when we
rc=$?
# zap our watchdog if it's still there, since we no longer need it
2>>/dev/null kill -0 $killerpid && kill -15 $killerpid
exit $rc
다른 스크립트는 온라인입니다 http://www.cs.tufts.edu/~nr/drop/timeout.
trap 'kill $(ps -L $! -o pid=); exit 30' 30
echo kill -30 $$ 2\>/dev/null | at $1 2>/dev/null
shift; eval $@ &
wait