2015-01-11 9 views
0

예기치 않게 교수형에 처하지 않는 Perl 스크립트의 문제를 해결하고 있습니다. 나는 펄을 모른다. 마침내 문제를 파일 경로 문자열로 추적했습니다. 이 코드는 작동 : 나는 밑줄을 포함하는 파일 이름을 변경하면왜 경로 이름에 밑줄 문자로 인해 Perl 스크립트가 멈 춥니 다?

$eng_morph = "~/datafile.en.db"; 
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph"; 

, 두 번째 줄은 영원히 중단 :

$eng_morph = "~/datafile.en_us.db"; 
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph"; 

구문에 문제가 있습니까? 밑줄을 허용 할 수있는 방법이 있습니까?

저는 우분투 14.04를 사용하고 있습니다.

리눅스 아수스 노트북 3.13.0-43 제네릭 # 72 - 우분투 SMP 월 12월 8일 세계 협정시 19시 35분 6초 2014 x86_64에의 x86_64에의 x86_64의 GNU/리눅스

: 다음은 uname 출력입니다 또한 배포판에 기본 Perl을 사용하고 있습니다. 그 버전 출력된다 :

이 41 등록 패치 ( x86_64에-리눅스 GNU 스레드 및 멀티 위해 만들어진 펄 5 버전 (18), 서브 2 (v5.18.2)이며, 참조 펄 -V 위한 자세한 내용)

+4

코드와 관련이없는 버그가 있습니다.'||'은 (는)'또는'여야합니다. '||'는 우선 순위가 높기 때문에 넥타이가 실패 할 때 죽는 대신에 0664가 거짓 일 때 죽어 가고 있습니다 (절대로 없습니다) – ysth

+0

@ysth - "관련이 없습니다". 어쩌면이 오류는 실제 문제를 가리는 것이며 "결코 그렇지 않다"죽어가는 부분이 이어 나갈 수 있습니다. Perl에 익숙하지 않고 수정 구문을 이해하지 못합니다. 시도 할 수 있도록 답변에 전체 수정을 넣으시겠습니까? – tahoar

답변

0

이 문제는 간헐적이었습니다. 간헐적으로 발생하는 많은 문제가 있기 때문에 스레드 문제로 판명되었습니다. 단서는 출력 폴더에 홀수 파일 ("~/_db_datafile.en.db" ...)이 있거나 정의 된 출력 파일 이름 앞에 "~/_db_"이 붙는 것입니다. 이 출력 파일은 원하는 출력 파일이 2 또는 3 메가 바이트 였을 때 0에서 14K 바이트까지였습니다.Perl tie() 함수가 DB 파일을 만드는 동안 중단 된 것처럼 보입니다.

subprocess.Popen() 파이핑에서 비 차단 스레드를 사용하는 Python 스크립트에서 문제의 코드가 호출되고있었습니다. Python 스크립트는 Perl 스크립트를 생성하고 계속 진행됩니다. Perl 스크립트가 여전히 DB 파일을 생성하는 동안 파이썬의 비 차단 스레드는 파이핑 데이터를 시작했습니다. 이렇게하면 Perl 스크립트의 파일 생성이 중지되고 lockup이 발생합니다.

파일 이름의 밑줄은이 오류의 첫 번째 간헐적 인 인스턴스이며 궁극적으로이 문제와 관련이 없습니다.

해결 방법 파이썬 코드에 while not os.path.exists(eng_morph): 루프를 간단하게 작성하여 적절한 DB 파일이 존재할 때까지 일시 중지하십시오.

1

파일 이름이 아닌 해당 특정 DB 파일에 거의 확실한 문제가 있습니다.

DB 파일이 어떤 방식으로 손상되었거나 서버의 기존 프로세스에서 파일이 열려 잠겨 있습니다.

다른 프로세스에 파일이 열려 있는지 확인하고 (lsof 사용) 데이터베이스와 비슷하지만 "."로 시작하는 파일을 확인하십시오. 동일한 디렉토리에 있습니다. 수

+0

출력 폴더가이 출력용으로 특별히 생성되었으므로 손상된 DB 파일이 될 수 없습니다. Perl 코드는 빈 출력 폴더에 DB 파일을 만듭니다. 그러나 나는 그것이 밑줄이 아닌 것에 동의한다. 잠금 문제는 마지막으로 밑줄이없는 파일 이름으로 발생했습니다. – tahoar

1
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph"; 

요구 (즉 ls -a ~ | grep -i en_us 할)

tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664 or die "Cannot open dbmfile $eng_morph"; 

또는

tie(%eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664) || die "Cannot open dbmfile $eng_morph"; 

|| 높은 우선 오퍼레이터 때문에

.

tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, (0664 || die "Cannot open dbmfile $eng_morph"); 

||이 자연스럽게 그 결과를 반환하는 식으로 사용할 수 있도록 설계되었습니다; 그렇지 않은 경우는 다음과 같이 해석됩니다 or은 본질적으로 다른 표현식 사이의 흐름 제어에 사용되도록 설계되었습니다 (두 개는 우선 순위 만 다름).

이 오류로 인해 연결이 끊어지면 코드는 계속 실행되지만 % eng_morph는 일반 해체 된 해시로 남습니다.

+0

고마워요, ysth. 코드를 업데이트했지만 중단 문제를 해결하지 못하거나 근본적인 오류를 드러내지 않았습니다. 나는 그러나, 문제를 찾아 내 자신의 대답을 썼다. – tahoar