[unix] 유닉스에서 “텍스트 파일 사용중”메시지를 생성하는 것은 무엇입니까?
“텍스트 파일 사용 중”오류가 발생하는 작업은 무엇입니까? 정확히 말할 수 없습니다.
임시 파이썬 스크립트 (tempfile 사용)를 만들고 execl을 사용한다는 사실과 관련이 있다고 생각하지만 execl은 실행중인 파일을 변경한다고 생각합니다.
답변
이 오류는 다른 프로세스 나 사용자가 파일에 액세스하고 있음을 의미합니다. 사용하여 lsof
다른 프로세스를 사용하고있는 것을 확인 할 수 있습니다. kill
필요한 경우 명령을 사용하여 명령을 종료 할 수 있습니다 .
답변
그 메시지를 본 지 오래되었지만, System V R3에서 널리 사용되거나 수십 년 전에 널리 사용되었습니다. 당시에는 실행중인 프로그램 실행 파일을 변경할 수 없었습니다.
예를 들어, 나는 make
이라는 이름 의 workalike rmk
를 만들고 있었고 잠시 후 자체 유지 관리했습니다. 개발 버전을 실행하고 새 버전을 빌드하도록했습니다. 제대로 작동하려면 해결 방법을 사용해야했습니다.
gcc -g -Wall -o rmk1 main.o -L. -lrmk -L/Users/jleffler/lib/64 -ljl
if [ -f rmk ] ; then mv rmk rmk2 ; else true; fi ; mv rmk1 rmk
그래서, ‘바쁜 텍스트 파일’문제를 방지하기 위해, 빌드가 새 파일을 생성 rmk1
한 후 기존의 이동 rmk
로를 rmk2
한 다음 새로 지어 이동 (링크 해제했다 이름 바꾸기 문제가 아니었다) rmk1
에 rmk
.
나는 현대 시스템에서 오류를 꽤 오랫동안 보지 못했습니다 …하지만 종종 프로그램을 스스로 재구성하는 것은 아닙니다.
답변
답변
최소 실행 가능 C POSIX 재생 예
무슨 일이 일어나고 있는지 더 잘 보려면 기본 API를 이해하는 것이 좋습니다.
sleep.c
#define _XOPEN_SOURCE 700
#include <unistd.h>
int main(void) {
sleep(10000);
}
busy.c
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void) {
int ret = open("sleep.out", O_WRONLY|O_TRUNC);
assert(errno == ETXTBSY);
perror("");
assert(ret == -1);
}
컴파일하고 실행하십시오.
gcc -std=c99 -o sleep.out ./sleep.c
gcc -std=c99 -o busy.out ./busy.c
./sleep.out &
./busy.out
busy.out
assert를 전달하고 perror
출력합니다.
Text file busy
그래서 우리는 메시지가 glibc 자체로 하드 코딩 된 것으로 추론합니다.
또는
echo asdf > sleep.out
Bash 출력을 만듭니다.
-bash: sleep.out: Text file busy
보다 복잡한 응용 프로그램의 경우 다음을 통해 확인할 수도 있습니다 strace
.
strace ./busy.out
포함하는:
openat(AT_FDCWD, "sleep.out", O_WRONLY) = -1 ETXTBSY (Text file busy)
Ubuntu 18.04, Linux 커널 4.15.0에서 테스트되었습니다.
unlink
처음 에는 오류가 발생하지 않습니다
notbusy.c :
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void) {
assert(unlink("sleep.out") == 0);
assert(open("sleep.out", O_WRONLY|O_CREAT) != -1);
}
그런 다음 위와 비슷하게 컴파일하고 실행하면 해당 주장이 통과합니다.
이것은 왜 특정 프로그램에서는 작동하지만 다른 프로그램에서는 작동하지 않는지를 설명합니다. 예를 들어 :
gcc -std=c99 -o sleep.out ./sleep.c
./sleep.out &
gcc -std=c99 -o sleep.out ./sleep.c
두 번째 gcc
호출이에 쓰 더라도 오류가 발생하지 않습니다 sleep.out
.
간단히 strace
말하면 GCC가 쓰기 전에 먼저 연결을 끊는 것을 보여줍니다.
strace -f gcc -std=c99 -o sleep.out ./sleep.c |& grep sleep.out
포함한다 :
[pid 3992] unlink("sleep.out") = 0
[pid 3992] openat(AT_FDCWD, "sleep.out", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
실패하지 않는 이유 unlink
는 파일을 다시 쓰고 쓸 때 새 inode를 만들고 실행중인 실행 파일에 대한 임시 매달린 inode를 유지하기 때문입니다.
그러나 당신이 write
없는 경우 unlink
실행중인 실행 파일과 동일한 보호 된 inode에 쓰려고합니다.
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
파일은 실행중인 순수 프로 시저 (공유 텍스트) 파일이며 oflag는 O_WRONLY 또는 O_RDWR입니다.
남자 2 오픈
ETXTBSY
pathname은 현재 실행 중이고 쓰기 액세스가 요청 된 실행 가능 이미지를 나타냅니다.
답변
내 경우에는 csh 환경에서 셸 파일 (확장명이 .sh 인)을 실행하려고했지만 오류 메시지가 나타납니다.
bash로 실행하면 나를 위해 일했습니다. 예를 들어
bash file.sh
답변
phpredis
Linux 박스 에서 빌드 를 시도하는 경우 파일 sleep
을 실행하기 전에 명령을 사용하여 파일 권한 수정을 완료 할 시간을 주어야 합니다.
chmod a+x /usr/bin/php/scripts/phpize \
&& sleep 1 \
&& /usr/bin/php/scripts/phpize
답변
원인을 모르지만 신속하고 쉬운 해결 방법을 제공 할 수 있습니다.
방금 “cat> shScript.sh”(붙여 넣기, ^ Z) 후 CentOS 6에서이 이상한 점을 경험 한 다음 KWrite에서 파일을 편집했습니다. 이상하게도 스크립트 실행에 대한 식별 가능한 인스턴스 (ps -ef)가 없었습니다.
내 빠른 해결 방법은 단순히 “cp shScript.sh shScript2.sh”에 대한 것이었고 shScript2.sh를 실행할 수있었습니다. 그런 다음 둘 다 삭제했습니다. 끝난!