Что генерирует сообщение "текстовый файл занят" в Unix?

Какая операция генерирует ошибку "текстовый файл занят"? Я не могу точно сказать.

Я думаю, что это связано с тем, что я создаю временный python script (используя tempfile) и используя execl из него, но я думаю, что execl изменяет выполняемый файл.

Ответ 1

Эта ошибка означает, что какой-либо другой процесс или пользователь обращаются к вашему файлу. Используйте lsof, чтобы проверить, какие другие процессы используют его. Вы можете использовать команду kill, чтобы убить ее, если это необходимо.

Ответ 2

Это время, так как я видел это сообщение, но он был распространен в 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.

Я давно не видел ошибки в современной системе... но я не все, что часто перестраивает программы.

Ответ 3

  Это происходит при попытке записи в файл, который в данный момент выполняется ядром, или при выполнении файла, который в данный момент открыт для записи.

Источник: http://wiki.wlug.org.nz/ETXTBSY

Ответ 4

Пример минимального запуска 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 относится к исполняемому образу, который в данный момент выполняется, и был запрошен доступ для записи.

Ответ 5

В моем случае я пытался выполнить файл оболочки (с расширением .sh) в среде csh, и я получал это сообщение об ошибке.

просто работает с bash, это сработало для меня. Например

bash file.sh

Ответ 6

Не знаю причину, но я могу способствовать быстрой и легкой работе.

Я просто испытал эту эту странность в CentOS 6 после "cat > shScript.sh" (paste, ^ Z), а затем редактировал файл в KWrite. Как ни странно, не было видимого экземпляра (ps -ef) выполнения script.

Моя быстрая работа была просто "cp shScript.sh shScript2.sh", после чего я смог выполнить shScript2.sh. Затем я удалил оба. Готово!

Ответ 7

Вы можете обнаружить, что это более распространено в сетевых ресурсах CIFS/SMB. Windows не позволяет писать файл, когда что-то еще открывает этот файл, и даже если служба не Windows (это может быть какой-то другой продукт NAS), он, вероятно, воспроизведет такое же поведение. Потенциально, это может быть также проявление некоторой проблемы с базой NAS, смутно связанной с блокировкой/репликацией.

Ответ 8

Если вы пытаетесь построить phpredis в ящике Linux, вам может потребоваться время, чтобы завершить модификацию разрешений файла с помощью команды sleep перед запуском файла:

chmod a+x /usr/bin/php/scripts/phpize \
  && sleep 1 \
  && /usr/bin/php/scripts/phpize

Ответ 9

Один из моих впечатлений:

Я всегда меняю комбинацию клавиш по умолчанию для 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)

Ответ 10

Если вы запускаете .sh из ssh-соединения с помощью такого инструмента, как MobaXTerm, и если в указанном инструменте есть утилита автосохранения для редактирования удаленного файла с локального компьютера, он заблокирует файл.

Закрытие и повторное открытие сессии SSH решает ее.

Ответ 11

Я наткнулся на это в PHP при использовании fopen() в файле, а затем попытался unlink() его перед использованием fclose() на нем.

Нехорошо:

$handle = fopen('file.txt');
// do something
unlink('file.txt');

Хорошо:

$handle = fopen('file.txt');
// do something
fclose($handle);
unlink('file.txt');