[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한 다음 새로 지어 이동 (링크 해제했다 이름 바꾸기 문제가 아니었다) rmk1rmk.

나는 현대 시스템에서 오류를 꽤 오랫동안 보지 못했습니다 …하지만 종종 프로그램을 스스로 재구성하는 것은 아닙니다.


답변

커널에서 현재 실행중인 파일에 쓰려고하거나 현재 쓰기 위해 열려있는 파일을 실행할 때 발생합니다.

출처 : http://wiki.wlug.org.nz/ETXTBSY


답변

최소 실행 가능 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.outassert를 전달하고 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


답변

phpredisLinux 박스 에서 빌드 를 시도하는 경우 파일 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를 실행할 수있었습니다. 그런 다음 둘 다 삭제했습니다. 끝난!