2017-02-06 1 views
6

다른 프로세스가 쓰기 작업을 수행 할 때 명명 된 파이프를 만들었으므로 다른 프로세스가 올바르게 시작되었지만 PID를 모르고 있는지 확인하려고합니다. 컨텍스트는 running a command in screen이며 명령이 올바르게 시작되었는지 확인하십시오. 나는이 작동하지 않을 수 있습니다 기대했다 :명명 된 파이프/FIFO가 쓰기 용으로 열려 있는지 확인하십시오.

mkfifo /tmp/foo 
echo hello > /tmp/foo & 
lsof /tmp/foo 

슬프게도, lsofecho를보고하지 않습니다. inotifywait은 다른 옵션 일 수도 있지만 항상 설치되는 것은 아니며 일부 이벤트가 발생할 때까지 차단하기보다는 한 번 폴링하고 싶습니다.

명명 된 파이프가 쓰기 위해 열려 있는지 확인할 방법이 있습니까? 일반적으로 열려 있니?


UPDATE : 양쪽 끝이 연결되면

lsof가 작동하는 것 같다. 이것은 실제로 내 문제를 해결하지만 질문을 위해서 독자가없는 명명 된 파이프에 대한 초기 리디렉션을 감지 할 수 있는지 알고 싶습니다.

> mkfifo /tmp/foo 
> yes > /tmp/foo & 
> lsof /tmp/foo 
> cat /tmp/foo > /dev/null & 
> lsof /tmp/foo 
COMMAND PID  USER FD TYPE DEVICE SIZE/OFF  NODE  NAME 
yes  16915  user 1w FIFO 8,18  0t0 16660270 /tmp/foo 
cat  16950  user 3r FIFO 8,18  0t0 16660270 /tmp/foo 
+0

"쓰기 용으로 열기"라고 말하면 읽을 수있는 데이터가 있다는 것을 의미합니까? 쓰기가 불가능한 FIFO가 무엇입니까? – Fred

+1

당신이 찾고있는 대답이 아니지만, .pid 파일을 쓸 수도 있습니다. – teppic

+0

@Fred 질문이 이해가 안된다고 생각하면 "글쓰기를위한 열기"가 잘못된 용어 일 수 있습니다. 필자는 명명 된 파이프로 리디렉션되는 프로세스를 나열하는 것이 이상적입니다. 나는. 'mkfifo' 다음에 아무것도 없으면 목록은 비어 있어야합니다. 그런 다음'yes>/tmp/foo' 다음에 목록에서'yes'의 PID를보아야합니다. – jozxyqk

답변

2

업데이트 2 : inotify를-도구와 함께 연주 후, 명명 된 파이프가 쓰기 위해 열려하고 차단하는 통지를 얻을 수있는 방법이있을 것 같지 않습니다. 이것은 아마도 lsof이 리더와 라이터를 가질 때까지 파이프를 보이지 않는 이유 일 것입니다.

업데이트 : 명명 된 파이프를 조사한 후 명명 된 파이프와 함께 작동하는 방법이 있다고 생각하지 않습니다. 추론 :

  • 모든 제작자는이 경우에는 라이터 차단 않음 리더
  • 가 없으면 블록 (록킹에 의존하지 않음)라는 파이프 작가의 수를 제한 할 방법이 없다 독자 (아마도 한 커널 버퍼가 가득 아니기 때문에)

당신은 짧은 시간 초과로 파이프에 아무것도 기록하지 시도 할 수 있습니다. 타임 아웃이 끝나면 누군가가 이미 글쓰기를 위해 파이프를 연다는 것을 나타내는 쓰기가 차단됩니다.

참고 : 의견에서 지적했듯이 독자가 존재하고 아마도 충분히 빠르면 테스트 기록이 차단되지 않고 테스트가 본질적으로 실패합니다. 아래에서 cat 행을 주석 처리하여 테스트하십시오.

#!/bin/bash 

is_named_pipe_already_opened_for_writing() { 
    local named_pipe="$1" 
    # Make sure it's a named pipe 
    if ! [ -p "$named_pipe" ]; then 
     return 1 
    fi 
    # Try to write zero bytes in the background 
    echo -n > "$named_pipe" & 
    pid=$! 
    # Wait a short amount of time 
    sleep 0.1 
    # Kill the background process. If kill succeeds, then 
    # the write was blocked indicating that someone 
    # else is already writing to the named pipe. 
    kill $pid 2>/dev/null 
} 

PIPE=/tmp/foo 

# Ignore any bash messages from killing below 
trap : TERM 

mkfifo $PIPE 
# a writer 
yes > $PIPE & 
# a reader 
cat $PIPE >/dev/null & 

if is_named_pipe_already_opened_for_writing "$PIPE"; then 
    echo "$PIPE is already being written to by another process" 
else 
    echo "$PIPE is NOT being written to by another process" 
fi 

jobs -pr | kill 2>/dev/null 
rm -f $PIPE 
+0

예, 이것은 파이프에서 읽는 것이 없으면 작동합니다. – jozxyqk

+0

나는 그것을 테스트하지 않았다. 글쎄, 그건 좋지 않아. – Harvey

+0

특정 수면 지속 시간 (올바르게 이해할 경우 쓰기 테스트 백그라운드 프로세스가 종료되기에 충분한 시간을 제공해야 함)을 사용하면 약간 깨지기 쉬운 것 같습니다. 특정 상황 (예 : 높은 CPU 또는 IO로드)에서 예기치 않은 결과가 발생할 위험이 있습니까? – Fred

관련 문제