Respostas:
Este erro significa que algum outro processo ou usuário está acessando seu arquivo. Use lsofpara verificar quais outros processos estão usando. Você pode usar o killcomando para matá-lo, se necessário.
Faz um tempo desde que eu vi essa mensagem, mas costumava prevalecer no System V R3 ou cerca de algumas décadas atrás. Naquela época, isso significava que não era possível alterar um programa executável enquanto ele estava em execução.
Por exemplo, eu estava construindo um makeworkalike chamado rmk, e depois de um tempo ele se manteve. Eu rodaria a versão de desenvolvimento e a compilaria uma nova versão. Para fazê-lo funcionar, era necessário usar a solução alternativa:
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
Portanto, para evitar problemas com o 'arquivo de texto ocupado', a compilação criou um novo arquivo rmk1, depois moveu o antigo rmkpara rmk2(renomear não era um problema; desvincular era) e depois mudou o recém-criado rmk1para rmk.
Não vejo o erro em um sistema moderno há um bom tempo ... mas nem sempre os programas são reconstruídos.
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. Produzi a mensagem de erro "cp: não é possível criar o arquivo regular 'a.out': arquivo de texto ocupado" no meu novo Fedora.
unlinkpor padrão.
Isso ocorre quando você tenta gravar em um arquivo que está sendo executado atualmente pelo kernel ou executa um arquivo que está aberto para gravação no momento.
Exemplo mínimo de reprodução executável em C POSIX
Eu recomendo entender a API subjacente para ver melhor o que está acontecendo.
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);
}
Compile e execute:
gcc -std=c99 -o sleep.out ./sleep.c
gcc -std=c99 -o busy.out ./busy.c
./sleep.out &
./busy.out
busy.outpassa as afirmações e perrorproduz:
Text file busy
portanto, deduzimos que a mensagem está codificada na própria glibc.
Alternativamente:
echo asdf > sleep.out
produz saída Bash:
-bash: sleep.out: Text file busy
Para uma aplicação mais complexa, você também pode observá-la com strace:
strace ./busy.out
que contém:
openat(AT_FDCWD, "sleep.out", O_WRONLY) = -1 ETXTBSY (Text file busy)
Testado no Ubuntu 18.04, Linux kernel 4.15.0.
O erro não ocorre se você unlinkprimeiro
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);
}
Em seguida, compile e execute analogamente ao acima, e essas afirmações passam.
Isso explica por que funciona em determinados programas, mas não em outros. Por exemplo, se você fizer:
gcc -std=c99 -o sleep.out ./sleep.c
./sleep.out &
gcc -std=c99 -o sleep.out ./sleep.c
isso não gera um erro, mesmo que a segunda gccchamada esteja sendo gravada sleep.out.
Uma rápida stracemostra que o GCC primeiro se desvincula antes de escrever:
strace -f gcc -std=c99 -o sleep.out ./sleep.c |& grep sleep.out
contém:
[pid 3992] unlink("sleep.out") = 0
[pid 3992] openat(AT_FDCWD, "sleep.out", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
O motivo para não falhar é que, quando você unlinkreescreve o arquivo, ele cria um novo inode e mantém um inode temporário pendente para o arquivo executável em execução.
Mas, se você apenas ficar writesem unlink, ele tenta gravar no mesmo inode protegido que o executável em execução.
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
O arquivo é um arquivo de procedimento puro (texto compartilhado) que está sendo executado e oflag é O_WRONLY ou O_RDWR.
homem 2 aberto
ETXTBSY
nome do caminho refere-se a uma imagem executável que está sendo executada no momento e o acesso de gravação foi solicitado.
unlink . O Linux já leu o arquivo mais de uma vez após a primeira execchamada?
No meu caso, eu estava tentando executar um arquivo shell (com uma extensão .sh) em um ambiente csh e estava recebendo essa mensagem de erro.
apenas rodando com bash funcionou para mim. Por exemplo
bash file.sh
#!/bin/bashcabeçalho?
#!/usr/bin/cshou equivalente.
Se estiver tentando construir phpredisem uma caixa do Linux, talvez seja necessário tempo para concluir a modificação das permissões do arquivo, com um sleepcomando, antes de executar o arquivo:
chmod a+x /usr/bin/php/scripts/phpize \
&& sleep 1 \
&& /usr/bin/php/scripts/phpize
chmodque retornaria antes que as permissões fossem definidas. Isso pode ser um problema do sistema de arquivos.
Não sei a causa, mas posso contribuir com uma solução rápida e fácil.
Acabei de experimentar essa essa estranheza no CentOS 6 depois de "cat> shScript.sh" (colar, ^ Z) e depois editar o arquivo no KWrite. Estranhamente, não havia instância discernível (ps -ef) do script em execução.
Meu trabalho rápido foi simplesmente "cp shScript.sh shScript2.sh", depois pude executar o shScript2.sh. Então eu apaguei os dois. Feito!
catprocesso. Da próxima vez, use ^ D, não ^ Z.
Você pode achar que isso é mais comum em compartilhamentos de rede CIFS / SMB. O Windows não permite que um arquivo seja gravado quando algo mais o abrir, e mesmo que o serviço não seja o Windows (pode ser outro produto NAS), provavelmente reproduzirá o mesmo comportamento. Potencialmente, também pode ser uma manifestação de algum problema subjacente do NAS vagamente relacionado ao bloqueio / replicação.
Se você estiver executando o .sh de uma conexão ssh com uma ferramenta como MobaXTerm, e se a ferramenta possuir um utilitário de gravação automática para editar arquivos remotos da máquina local, isso bloqueará o arquivo.
Fechar e reabrir a sessão SSH a resolve.
Uma das minhas experiências:
Sempre altero o atalho de teclado padrão do Chrome por meio de engenharia reversa. Após a modificação, esqueci de fechar o Chrome e executei o seguinte:
sudo cp chrome /opt/google/chrome/chrome
cp: cannot create regular file '/opt/google/chrome/chrome': Text file busy
Usando strace, você pode encontrar mais detalhes:
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)
Me deparei com isso no PHP ao usar fopen()um arquivo e depois tentar unlink()antes de usarfclose() -lo.
Nada de bom:
$handle = fopen('file.txt');
// do something
unlink('file.txt');
Boa:
$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 busyerro específico é tentar modificar um executável enquanto está em execução. O "Texto" aqui refere-se ao fato de que o arquivo que está sendo modificado é o segmento de texto para um programa em execução. Este é um caso muito especial, e não o genérico que sua resposta parece sugerir. Mesmo assim, sua resposta não está totalmente incorreta.