2009-10-31 2 views
2

이것은 이상한 일이며, 범인이 누구인지는 잘 모르겠습니다.FreeBSD, MySQL, Perl, bash : 명명 된 파이프에서 간헐적 인 블로킹?

FreeBSD (6.2)에서 스크립팅을하고 있습니까? 이는 다음 *** bash는 광범위하게 사용합니다 ***주의 :. do_something 파이프 라인에서 읽지 않습니다 (펄) 다소 crufty 유틸리티입니다 "

do_something <(mysql --skip-column-names -B -e 'select ... from ... where ...;') 

... 내가 사용하는 경우 일반 파일 그것이 잘 작동합니다. 쿼리 (형태 while read x y z <&4; do ...의 루프에 의해 다음의 이러한 종류와 exec 4< <(...) 같은 것들을 사용하여 내 bash는 스크립트가 결코 문제를 갖고있는 것 같다 없다. 그러나

, 펄 (5.8.x)가 보인다 정기적으로 차단 (외관상으로는 영원히). 사용 된 루틴을 사용하여 chomp(my $data = <MYDATA>);을 변경해 보았습니다. sysread 그리고 비교를 위해 Python에서 몇 가지 테스트 케이스를 작성했습니다. 이것들은 관용적 인 Perl 코드보다 훨씬 적은 빈도로 보일지도 모릅니다. (f.read() 또는 os.read(f.fileno()...)을 사용하는 파이썬 코드는이 문제에서 거의 똑같이 동작하는 것처럼 보입니다.

나는 ... <(cat ...) (여기에서 나는 고양이 일반 파일을 보내고있다)을 사용하여 문제를 재현 해 보았으며 그 실속을 결코 재연하지 않는 것으로 보인다.

ktrace 형태/kdump에에서 데이터를 훑어 봤는데 ...하지만 난 지금까지 트러스가 ... 그래서에서 무슨 일이 일어나고 있는지 파악되지 않은 또는 솔라리스 리눅스 strace를 더 알고 있어요 아직 거기.

파이썬을 사용하여 같은 문제를 재현했기 때문에 대부분 펄을 배제 할 수 있다고 가정합니다 ... 배시은 여기에 아무 것도하지 않을 수 있습니다. /var/tmp/sh-np-xxx 그리고 그 프로세스까지 연결하십시오.

mysql 셸/유틸리티로 인해이 문제가 발생할 수 있습니까? 나는 다른 것으로부터 그것을 본 것 같지 않습니다 (예 : 고양이 또는 dd). Linux에서이 시나리오를 테스트하지는 않았지만, Linux에서 수년간 <(...) (프로세스 대체)을 사용해 왔지만이 문제를 본 적이 없습니다.

FreeBSD 문제입니까?

확실히 임시 파일을 사용하여 문제를 해결할 수 있습니다 ...하지만 오히려 왜 이런 일을하는지 (그리고 임시 파일이 수반하는 인종 및 정리 지저분한 일을 피하십시오) 이해해야합니다.

제안 사항?

답변

4

mysql의 출력에서 ​​작동하는 것과 파일에서 직접 작동하는 것의 큰 차이는 타이밍입니다. 펄 프로세스가 멈 추면 커다란 문제는 "왜 앞으로 진행되지 않는가"라는 것입니다. ps에 "l"옵션을 사용하면 perl 프로세스의 대기 채널을 볼 수 있습니다. 그렇게하면 읽음으로 막혔는지 또는 다른 일이 일어나고 있는지 알 수 있습니다. 파이프 입력에서 실제로 차단 된 경우 perl에 대한 MWCHAN 항목이 "piperd"가 될 것으로 예상합니다.

같은 정보가 mysql 프로세스에서 흥미로울 것입니다.

귀하의 Python 테스트 코드는 어떻게 생겼습니까?

bashism을 피하면서 이것을 쓰는 또 다른 방법은 다음과 같습니다.

mysql --skip-column-names -B -e 'select ... from ... where ...;' | do_something /dev/stdin 

다른 흥미로운 질문 :

  • 가 --unbuffered 옵션은 아무것도 변경 MySQL로합니까 그건 당신이 떠들썩한 파티를 배제 할 수 있도록 것인가?

  • dd를 통해 mysql 출력을 파이핑하면 아무 것도 변경되지 않습니까? (예 : "펄 스크립트 < (MySQL의 ... |

요약 DD) :.. 추가 정보 필요

+0

는 <(... 시도 | 고양이)와 <(... | DD 학사 = 1) 행동에 변화가없는 해킹. 나는 mysql의 --unbuffered 옵션을 곧 시험해 보겠다. 흥미로운 것으로 들리 겠지만 전에는 알지 못했다. –

+0

정말 흥미로운 점은 mysql과 perl의 상태이다. 프로세스가 앞으로 진행하는 것을 멈추는 것처럼 보일 때 프로세스가됩니다. 'dd'테스트는 작은 버퍼보다 ​​큰 버퍼를 사용하는 것이 훨씬 더 재미있을 것입니다. 버퍼 크기를 예상 된 출력보다 크게 만들면 dd가 거의 동일한 출력을 내 보냅니다 방법은 임시 파일이지만 임시 파일은 사용하지 마십시오. – janm

+0

솔라리스에서'truss -eaf something 2> (텍스트를 소비하는 명령)'형식의 어떤 것을 실행하는 비슷한 문제를보고 있습니다. ' 'dd bs = 1' 것은 도움이되지 않았습니다. '우차'에는'?'이 있습니다. 무엇이 당신을 위해 그것을 끝내 었는가? –

관련 문제