유닉스에서 "텍스트 파일 사용중"메시지를 생성하는 것은 무엇입니까?
"텍스트 파일 사용 중"오류가 발생하는 작업은 무엇입니까? 정확히 말할 수 없습니다.
임시 파이썬 스크립트 (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
.
나는 현대 시스템에서 오류를 꽤 오랫동안 보지 못했습니다 ...하지만 종종 프로그램을 스스로 재구성하는 것은 아닙니다.
커널에서 현재 실행중인 파일에 쓰려고하거나 현재 쓰기 위해 열려있는 파일을 실행할 때 발생합니다.
출처 : 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.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
The reason it does not fail is that when you unlink
and re-write the file, it creates a new inode, and keeps a temporary dangling inode for the running executable file.
But if you just write
without unlink
, then it tries to write to the same protected inode as the running executable.
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
The file is a pure procedure (shared text) file that is being executed and oflag is O_WRONLY or O_RDWR.
man 2 open
ETXTBSY
pathname refers to an executable image which is currently being executed and write access was requested.
In my case, I was trying to execute a shell file (with an extension .sh) in a csh environment, and I was getting that error message.
just running with bash it worked for me. For example
bash file.sh
Don't know the cause but I can contribute a quick and easy work around.
I just experienced this this oddity on CentOS 6 after "cat > shScript.sh" (paste, ^Z) then editing the file in KWrite. Oddly there was no discernible instance (ps -ef) of the script executing.
My quick work around was simply to "cp shScript.sh shScript2.sh" then I was able to execute shScript2.sh. Then I deleted both. Done!
You may find this to be more common on CIFS/SMB network shares. Windows doesn't allow for a file to be written when something else has that file open, and even if the service is not Windows (it might be some other NAS product), it will likely reproduce the same behaviour. Potentially, it might also be a manifestation of some underlying NAS issue vaguely related to locking/replication.
If trying to build phpredis
on a Linux box you might need to give it time to complete modifying the file permissions, with a sleep
command, before running the file:
chmod a+x /usr/bin/php/scripts/phpize \
&& sleep 1 \
&& /usr/bin/php/scripts/phpize
One of my experience:
I always change the default keyboard shortcut of Chrome through reverse engineering. After modification, I forgot to close Chrome and ran the following:
sudo cp chrome /opt/google/chrome/chrome
cp: cannot create regular file '/opt/google/chrome/chrome': Text file busy
Using strace, you can find the more details:
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)
If you are running the .sh from a ssh connection with a tool like MobaXTerm, and if said tool has an autosave utility to edit remote file from local machine, that will lock the file.
Closing and reopening the SSH session solves it.
I came across this in PHP when using fopen()
on a file and then trying to unlink()
it before using fclose()
on it.
No good:
$handle = fopen('file.txt');
// do something
unlink('file.txt');
Good:
$handle = fopen('file.txt');
// do something
fclose($handle);
unlink('file.txt');
참고URL : https://stackoverflow.com/questions/16764946/what-generates-the-text-file-busy-message-in-unix
'Programing' 카테고리의 다른 글
Typescript 매개 변수 이름에서 물음표는 무엇입니까 (0) | 2020.07.13 |
---|---|
수입을 조롱하는 방법 (0) | 2020.07.13 |
Markdown을 사용하여 단락에 클래스 이름을 정의 할 수 있습니까? (0) | 2020.07.13 |
MVC에 다시 쓴 후 GUI가 작동하지 않음 (0) | 2020.07.13 |
Apache Thrift, Google Protocol Buffers, MessagePack, ASN.1 및 Apache Avro의 주요 차이점은 무엇입니까? (0) | 2020.07.13 |