Ответы:
Эта ошибка означает, что к вашему файлу обращается какой-то другой процесс или пользователь. Используйте, 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
. Выдало сообщение об ошибке «cp: невозможно создать обычный файл 'a.out': текстовый файл занят» в моей новой Fedora.
unlink
по умолчанию.
Это происходит, когда вы пытаетесь выполнить запись в файл, который в данный момент выполняется ядром, или выполняете файл, который в данный момент открыт для записи.
Источник: http://wiki.wlug.org.nz/ETXTBSY
Минимальный пример воспроизведения POSIX на C
Я рекомендую разобраться в базовом 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
это не вызывает ошибки, даже если второй 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
и перезаписываете файл, он создает новый индексный дескриптор и сохраняет временный висячий индексный дескриптор для запущенного исполняемого файла.
Но если у вас просто write
нет unlink
, тогда он пытается записать в тот же защищенный индекс, что и запущенный исполняемый файл.
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
Файл представляет собой файл чистой процедуры (общий текст), который выполняется и имеет значение O_WRONLY или O_RDWR.
человек 2 открытый
ETXTBSY
pathname относится к исполняемому образу, который в настоящее время выполняется, и был запрошен доступ на запись.
unlink
. Считывает ли Linux когда-либо файл более одного раза после первого exec
вызова?
В моем случае я пытался запустить файл оболочки (с расширением .sh) в среде csh и получал это сообщение об ошибке.
просто работая с 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
что вернусь до того, как будут установлены разрешения. Это может быть проблема с файловой системой.
Не знаю причины, но я могу помочь быстро и легко решить эту проблему.
Я только что испытал эту странность в CentOS 6 после "cat> shScript.sh" (вставить, ^ Z), а затем отредактировав файл в KWrite. Как ни странно, не было заметного экземпляра (ps -ef) выполнения скрипта.
Моей быстрой работой было просто "cp shScript.sh shScript2.sh", после чего я смог запустить shScript2.sh. Потом удалил оба. Готово!
cat
процесс. В следующий раз используйте ^ D, а не ^ Z.
Вы можете обнаружить, что это чаще встречается в общих сетевых папках CIFS / SMB. Windows не позволяет записывать файл, когда этот файл открыт чем-то другим, и даже если это служба, отличная от Windows (это может быть другой продукт NAS), она, скорее всего, будет воспроизводить то же поведение. Потенциально это также может быть проявлением некоторой основной проблемы NAS, нечетко связанной с блокировкой / репликацией.
Если вы запускаете .sh из ssh-соединения с помощью такого инструмента, как MobaXTerm, и если в указанном инструменте есть утилита автосохранения для редактирования удаленного файла с локального компьютера, это заблокирует файл.
Ее решает закрытие и повторное открытие сеанса 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)
Я столкнулся с этим в PHP при использовании fopen()
в файле, а затем пытался сделать 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
ошибка связана с попыткой изменить исполняемый файл во время его выполнения. «Текст» здесь относится к тому факту, что изменяемый файл является текстовым сегментом для запущенной программы. Это очень частный случай, а не тот общий, который, кажется, предполагает ваш ответ. Тем не менее, ваш ответ не совсем неверен.