回答:
このエラーは、他のプロセスまたはユーザーがファイルにアクセスしていることを意味します。lsof
他のプロセスがそれを使用しているものを確認するために使用します。kill
必要に応じて、コマンドを使用して強制終了できます。
私がそのメッセージを見たのは久しぶりですが、以前はSystem V R3やその数十年前に流行していました。当時は、実行中にプログラムの実行可能ファイルを変更することはできませんでした。
たとえば、私はmake
と呼ばれる仕組みを構築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
アサートを渡し、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
2番目の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
、ファイルを再書き込みすると、新しいiノードが作成され、実行中の実行可能ファイル用に一時的なぶら下がりiノードが保持されるためです。
しかし、がwrite
ない場合unlink
、実行中の実行可能ファイルと同じ保護されたiノードに書き込もうとします。
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
ファイルは実行中の純粋なプロシージャ(共有テキスト)ファイルで、oflagはO_WRONLYまたはO_RDWRです。
男2オープン
ETXTBSY
pathnameは、現在実行中であり、書き込みアクセスが要求された実行可能イメージを指します。
unlink
。Linuxは、最初のexec
呼び出し後にファイルを2回以上読み取ることはありますか?
私の場合、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)を実行し、KWriteでファイルを編集した後、CentOS 6でこの奇妙な問題を経験しました。奇妙なことに、実行中のスクリプトの識別可能なインスタンス(ps -ef)がありませんでした。
私の簡単な回避策は、単に「cp shScript.sh shScript2.sh」を実行することでした。その後、shScript2.shを実行することができました。次に、両方を削除しました。できた!
cat
。次回は^ Zではなく^ Dを使用してください。
私の経験の1つ:
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
特定の誤差は、それが実行中に実行可能ファイルを変更しようとしている程度です。ここで「テキスト」とは、変更されるファイルが実行中のプログラムのテキストセグメントであることを意味します。これは非常に特殊なケースであり、回答が示唆する一般的なケースではありません。それでも、あなたの答えは完全に間違っているわけではありません。