Yanıtlar:
Bu hata, başka bir işlemin veya kullanıcının dosyanıza erişmekte olduğu anlamına gelir. lsof
Başka hangi işlemlerin kullandığını kontrol etmek için kullanın . kill
Gerekirse onu öldürmek için komutu kullanabilirsiniz .
Bu mesajı görmeyeli epey oldu, ama eskiden System V R3'te ya da birkaç on yıl önce yaygındı. O zamanlar bu, çalıştırılabilir bir programı çalışırken değiştiremeyeceğiniz anlamına geliyordu.
Örneğin ben bir iş make
yapıyordum rmk
ve bir süre sonra kendi kendini idame ettiriyordum. Geliştirme sürümünü çalıştırır ve yeni bir sürüm oluşturmasını isterdim. Çalışması için geçici çözümü kullanmak gerekiyordu:
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
Yani, 'meşgul metin dosyası' ile sorunları önlemek için, yapı yeni bir dosya oluşturdu rmk1
, sonra eski taşındı rmk
etmek rmk2
ve sonra yeni inşa taşındı; (unlink oldu yeniden adlandırma bir sorun değildi) rmk1
için rmk
.
Bir süredir modern bir sistemde hatayı görmedim ... ama çoğu zaman kendi kendini yeniden inşa eden programlara sahip değilim.
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
. Yeni Fedora'mda "cp: normal dosya 'a.out' yaratılamıyor: Metin dosyası meşgul" hata mesajını oluşturdu.
unlink
varsayılan olarak yapıyorsa .
Bu, çekirdek tarafından o anda yürütülmekte olan bir dosyaya yazmaya çalıştığınızda veya o anda yazmak için açık olan bir dosyayı çalıştırdığınızda oluşur.
Kaynak: http://wiki.wlug.org.nz/ETXTBSY
Minimum çalıştırılabilir C POSIX çoğaltma örneği
Neler olduğunu daha iyi görmek için temel API'yi anlamanızı öneririm.
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);
}
Derleyin ve çalıştırın:
gcc -std=c99 -o sleep.out ./sleep.c
gcc -std=c99 -o busy.out ./busy.c
./sleep.out &
./busy.out
busy.out
savları ve perror
çıktıları geçer :
Text file busy
bu yüzden mesajın glibc içinde kodlanmış olduğu sonucuna vardık.
Alternatif:
echo asdf > sleep.out
Bash çıktısını yapar:
-bash: sleep.out: Text file busy
Daha karmaşık bir uygulama için, bunu şu şekilde de gözlemleyebilirsiniz strace
:
strace ./busy.out
içerenler:
openat(AT_FDCWD, "sleep.out", O_WRONLY) = -1 ETXTBSY (Text file busy)
Ubuntu 18.04, Linux kernel 4.15.0'da test edilmiştir.
Hata eğer olmaz unlink
ilk
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);
}
Sonra yukarıdakilere benzer şekilde derleyin ve çalıştırın ve bu iddialar geçer.
Bu, neden bazı programlar için işe yaradığını ama diğerleri için çalışmadığını açıklar. Örneğin, yaparsanız:
gcc -std=c99 -o sleep.out ./sleep.c
./sleep.out &
gcc -std=c99 -o sleep.out ./sleep.c
ikinci gcc
çağrı adresine yazsa bile bu bir hata oluşturmaz sleep.out
.
Hızlı bir şekilde strace
GCC'nin yazmadan önce bağlantıyı kaldırdığını gösterir:
strace -f gcc -std=c99 -o sleep.out ./sleep.c |& grep sleep.out
içerir:
[pid 3992] unlink("sleep.out") = 0
[pid 3992] openat(AT_FDCWD, "sleep.out", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
Başarısız olmamasının nedeni unlink
, dosyayı yeniden yazdığınızda yeni bir inode oluşturması ve çalışan yürütülebilir dosya için geçici bir sarkan inode tutmasıdır.
Ama eğer write
olmadan unlink
, o zaman çalışan yürütülebilir aynı korumalı inode'a yazmaya çalışır.
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
Dosya, yürütülmekte olan saf bir prosedür (paylaşılan metin) dosyasıdır ve çoğu zaman O_WRONLY veya O_RDWR'dir.
adam 2 açık
ETXTBSY
yol adı, şu anda yürütülmekte olan ve yazma erişimi talep edilen çalıştırılabilir bir görüntüyü ifade eder.
unlink
. Linux, ilk exec
aramadan sonra dosyayı bir kereden fazla okur mu?
Benim durumumda, bir csh ortamında bir kabuk dosyası (.sh uzantılı) çalıştırmaya çalışıyordum ve bu hata mesajını alıyordum.
sadece bash ile çalışıyor, benim için çalıştı. Örneğin
bash dosyası.sh
#!/bin/bash
Başlığı var mıydı ?
#!/usr/bin/csh
Veya eşdeğerini kullanmayı denemek isteyebilirsiniz .
phpredis
Bir Linux kutusu üzerinde derleme yapmaya sleep
çalışıyorsanız, dosyayı çalıştırmadan önce bir komutla dosya izinlerini değiştirmeyi tamamlaması için ona zaman vermeniz gerekebilir :
chmod a+x /usr/bin/php/scripts/phpize \
&& sleep 1 \
&& /usr/bin/php/scripts/phpize
chmod
İzinler ayarlanmadan geri döneceğini sanmıyorum . Bu bir dosya sistemi sorunu olabilir.
Nedeni bilmiyorum ama hızlı ve kolay bir çalışma ile katkıda bulunabilirim.
Bu tuhaflığı CentOS 6'da "cat> shScript.sh" (yapıştırma, ^ Z) sonrasında ve ardından dosyayı KWrite'de düzenledikten sonra yaşadım. İşin garibi, çalıştırılan betiğin fark edilebilir bir örneği (ps -ef) yoktu.
Hızlı çalışmam sadece "cp shScript.sh shScript2.sh" oldu ve ardından shScript2.sh'yi çalıştırabildim. Sonra ikisini de sildim. Bitti!
cat
işlemi. Bir dahaki sefere ^ Z değil, ^ D kullanın.
Bunun CIFS / SMB ağ paylaşımlarında daha yaygın olduğunu görebilirsiniz. Windows, başka bir şey açık olduğunda bir dosyanın yazılmasına izin vermez ve hizmet Windows olmasa bile (başka bir NAS ürünü olabilir), muhtemelen aynı davranışı yeniden oluşturacaktır. Potansiyel olarak, kilitlenme / çoğaltma ile belirsiz bir şekilde ilgili bazı temel NAS sorununun bir göstergesi de olabilir.
.Sh dosyasını MobaXTerm gibi bir araçla ssh bağlantısından çalıştırıyorsanız ve söz konusu aracın yerel makineden uzak dosyayı düzenlemek için bir otomatik kaydetme yardımcı programı varsa, bu, dosyayı kilitleyecektir.
SSH oturumunu kapatmak ve yeniden açmak sorunu çözer.
Deneyimlerimden biri:
Her zaman tersine mühendislik yoluyla Chrome'un varsayılan klavye kısayolunu değiştiririm. Değişiklikten sonra Chrome'u kapatmayı unuttum ve aşağıdakileri çalıştırdım:
sudo cp chrome /opt/google/chrome/chrome
cp: cannot create regular file '/opt/google/chrome/chrome': Text file busy
Strace kullanarak daha fazla ayrıntı bulabilirsiniz:
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)
PHP'de fopen()
bir dosya üzerinde kullanırken ve daha sonra unlink()
onu kullanmadan önce onu denerken karşılaştım fclose()
.
İyi değil:
$handle = fopen('file.txt');
// do something
unlink('file.txt');
İyi:
$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
hata, çalıştırılırken bir yürütülebilir dosyayı değiştirmeye çalışmakla ilgilidir. Buradaki "Metin", değiştirilmekte olan dosyanın çalışan bir programın metin bölümü olduğu gerçeğini ifade eder . Bu çok özel bir durumdur ve cevabınızın önerdiği genel durum değil. Öyle olsa bile, cevabınız tamamen yanlış değil.