Відповіді:
Ця помилка означає, що якийсь інший процес або користувач отримує доступ до вашого файлу. Використовуйте, 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(перейменування не було проблемою, Unlink було), а потім переїхав недавно побудований 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
Мінімальний приклад відтворення C POSIX
Рекомендую розібратися в базовому API, щоб краще зрозуміти, що відбувається.
сон.c
#define _XOPEN_SOURCE 700
#include <unistd.h>
int main(void) {
sleep(10000);
}
занято.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перезаписуванні файлу він створює новий inode і зберігає тимчасовий висячий inode для запущеного виконуваного файлу.
Але якщо ви просто writeбез цього unlink, то він намагається записати в той самий захищений inode, що і запущений виконуваний файл.
POSIX 7 open()
http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
[ETXTBSY]
Файл являє собою чисту процедуру (спільний текст), який виконується, а oflag - O_WRONLY або O_RDWR.
людина 2 відкрити
ETXTBSY
ім'я шляху відноситься до виконуваного зображення, яке зараз виконується, і запит на доступ до запису.
unlink. Чи читає Linux ніколи не один раз після першого execдзвінка?
У моєму випадку я намагався виконати файл оболонки (з розширенням .sh) у середовищі csh, і я отримував це повідомлення про помилку.
просто біг з башем, це працювало на мене. Наприклад
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" (paste, ^ Z), після чого редагував файл у KWrite. Як не дивно, не було помітного екземпляра (ps -ef) сценарію виконання сценарію.
Моя швидка робота полягала в тому, щоб просто "cp shScript.sh shScript2.sh", тоді я зміг виконати shScript2.sh. Потім я видалив обидва. Готово!
catпроцес. Наступного разу використовуйте ^ D, а не ^ Z.
Це може бути більш поширеним у мережі CIFS / SMB. Windows не дозволяє записати файл, коли щось інше має цей файл, і навіть якщо служба не Windows (це може бути якийсь інший продукт NAS), вона, ймовірно, відтворює таку саму поведінку. Потенційно це також може бути проявом деякої основної проблеми NAS, нечітко пов'язаної з блокуванням / тиражуванням.
Один мій досвід:
Я завжди змінюю комбінацію клавіш 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Помилка в конкретному про спробу змінити виконуваний файл під час його виконання. Тут "Текст" посилається на те, що модифікований файл є текстовим сегментом для запущеної програми. Це дуже особливий випадок, а не загальний, про який, здається, пропонує ваша відповідь. Тим не менш, ваша відповідь не зовсім неправильна.