Какая операция генерирует ошибку "текстовый файл занят"? Я не могу точно сказать.
Я думаю, что это связано с тем, что я создаю временный python script (используя tempfile) и используя execl из него, но я думаю, что execl изменяет выполняемый файл.
Какая операция генерирует ошибку "текстовый файл занят"? Я не могу точно сказать.
Я думаю, что это связано с тем, что я создаю временный python script (используя 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
передает утверждения, а 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 относится к исполняемому образу, который в данный момент выполняется, и был запрошен доступ для записи.
В моем случае я пытался выполнить файл оболочки (с расширением .sh) в среде csh, и я получал это сообщение об ошибке.
просто работает с bash, это сработало для меня. Например
bash file.sh
Не знаю причину, но я могу способствовать быстрой и легкой работе.
Я просто испытал эту эту странность в CentOS 6 после "cat > shScript.sh" (paste, ^ Z), а затем редактировал файл в KWrite. Как ни странно, не было видимого экземпляра (ps -ef) выполнения script.
Моя быстрая работа была просто "cp shScript.sh shScript2.sh", после чего я смог выполнить shScript2.sh. Затем я удалил оба. Готово!
Вы можете обнаружить, что это более распространено в сетевых ресурсах CIFS/SMB. Windows не позволяет писать файл, когда что-то еще открывает этот файл, и даже если служба не Windows (это может быть какой-то другой продукт NAS), он, вероятно, воспроизведет такое же поведение. Потенциально, это может быть также проявление некоторой проблемы с базой NAS, смутно связанной с блокировкой/репликацией.
Если вы пытаетесь построить phpredis
в ящике Linux, вам может потребоваться время, чтобы завершить модификацию разрешений файла с помощью команды sleep
перед запуском файла:
chmod a+x /usr/bin/php/scripts/phpize \
&& sleep 1 \
&& /usr/bin/php/scripts/phpize
Один из моих впечатлений:
Я всегда меняю комбинацию клавиш по умолчанию для 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)
Если вы запускаете .sh из ssh-соединения с помощью такого инструмента, как MobaXTerm, и если в указанном инструменте есть утилита автосохранения для редактирования удаленного файла с локального компьютера, он заблокирует файл.
Закрытие и повторное открытие сессии SSH решает ее.
Я наткнулся на это в PHP при использовании fopen()
в файле, а затем попытался unlink()
его перед использованием fclose()
на нем.
Нехорошо:
$handle = fopen('file.txt');
// do something
unlink('file.txt');
Хорошо:
$handle = fopen('file.txt');
// do something
fclose($handle);
unlink('file.txt');