답변:
이 오류는 다른 프로세스 나 사용자가 파일에 액세스하고 있음을 의미합니다. 사용하여 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
.
나는 현대 시스템에서 오류를 꽤 오랫동안 보지 못했습니다 ...하지만 종종 프로그램을 스스로 재구성하는 것은 아닙니다.
echo -e '#include <unistd.h>\nint main(void){sleep (5);return 0;}' > slowprog.c && cc slowprog.c && cp a.out b.out && (./a.out &) ; sleep 1 && cp b.out a.out
입니다.. 새 Fedora에서 "cp : 일반 파일 'a.out'을 만들 수 없습니다 : 텍스트 파일 사용 중"이라는 오류 메시지가 표시되었습니다.
unlink
.
커널에서 현재 실행중인 파일에 쓰려고하거나 현재 쓰기 위해 열려있는 파일을 실행할 때 발생합니다.
최소 실행 가능 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은 현재 실행 중이고 쓰기 액세스가 요청 된 실행 가능 이미지를 나타냅니다.
unlink
. 리눅스는 첫 번째 exec
호출 후 파일을 두 번 이상 읽었 습니까?
내 경우에는 csh 환경에서 셸 파일 (확장명이 .sh 인)을 실행하려고했지만 오류 메시지가 나타납니다.
bash로 실행하면 나를 위해 일했습니다. 예를 들어
bash file.sh
#!/bin/bash
헤더를?
#!/usr/bin/csh
하거나 동등한 것을 시도 할 수 있습니다 .
phpredis
Linux 박스 에서 빌드 를 시도하는 경우 파일 sleep
을 실행하기 전에 명령을 사용하여 파일 권한 수정을 완료 할 시간을 주어야 합니다.
chmod a+x /usr/bin/php/scripts/phpize \
&& sleep 1 \
&& /usr/bin/php/scripts/phpize
chmod
권한이 설정되기 전에 돌아올 것이라고 생각하지 않습니다 . 파일 시스템 문제 일 수 있습니다.
원인을 모르지만 신속하고 쉬운 해결 방법을 제공 할 수 있습니다.
방금 "cat> shScript.sh"(붙여 넣기, ^ Z) 후 CentOS 6에서이 이상한 점을 경험 한 다음 KWrite에서 파일을 편집했습니다. 이상하게도 스크립트 실행에 대한 식별 가능한 인스턴스 (ps -ef)가 없었습니다.
내 빠른 해결 방법은 단순히 "cp shScript.sh shScript2.sh"에 대한 것이었고 shScript2.sh를 실행할 수있었습니다. 그런 다음 둘 다 삭제했습니다. 끝난!
cat
과정을. 다음에는 ^ Z가 아니라 ^ D를 사용하십시오.
MobaXTerm과 같은 도구를 사용하여 ssh 연결에서 .sh를 실행 중이고 해당 도구에 로컬 시스템에서 원격 파일을 편집하는 자동 저장 유틸리티가 있으면 파일이 잠 깁니다.
SSH 세션을 닫았다가 다시 열면 해결됩니다.
내 경험 중 하나 :
리버스 엔지니어링을 통해 항상 Chrome의 기본 키보드 단축키를 변경합니다. 수정 후 Chrome을 닫지 않고 다음을 실행했습니다.
sudo cp chrome /opt/google/chrome/chrome
cp: cannot create regular file '/opt/google/chrome/chrome': Text file busy
strace를 사용하면 자세한 내용을 확인할 수 있습니다.
sudo strace cp ./chrome /opt/google/chrome/chrome 2>&1 |grep 'Text file busy'
open("/opt/google/chrome/chrome", O_WRONLY|O_TRUNC) = -1 ETXTBSY (Text file busy)
fopen()
파일을 사용할 때 PHP 에서이 문제를 발견 한 다음 파일 unlink()
을 사용하기 전에 시도 fclose()
했습니다.
좋지 않다:
$handle = fopen('file.txt');
// do something
unlink('file.txt');
좋은:
$handle = fopen('file.txt');
// do something
fclose($handle);
unlink('file.txt');
root@h1:bin[0]# mount h2:/ /x
root@h1:bin[0]# cp /usr/bin/cat /x/usr/local/bin/
root@h1:bin[0]# umount /x
...
root@h2:~[0]# /usr/local/bin/cat
-bash: /usr/local/bin/cat: Text file busy
root@h2:~[126]#
ubuntu 20.04, 5.4.0-40-generic
nfsd problem, after reboot ok
Text file busy
오류는 실행 파일이 실행되는 동안 수정하려고합니다. 여기서 "텍스트"는 수정중인 파일이 실행중인 프로그램 의 텍스트 세그먼트 라는 사실을 나타냅니다 . 이것은 매우 특별한 경우이며 귀하의 답변이 제안하는 일반적인 것은 아닙니다. 그럼에도 불구하고 귀하의 답변이 완전히 틀린 것은 아닙니다.