Почему я не могу перезаписать файл обработанным значением?

Этот вопрос натолкнул на мысль, которую я не был уверен, что правильно понял. Я знаю, что использовать конвейеры вроде cat myfile | grep -v mypattern> myfile из-за того, как настроены дескрипторы файлов.Однако почему мы не можем просто использовать cat myfile | grep -v mypattern | tee myfile> / dev / null , чтобы изменить файл на месте? Есть ли какие-нибудь простые примеры, когда это не удается?

В частности, приводит ли это к повреждению или это больше не редактирование на месте, а перезапись?

Обновляя вопрос, я был бы признателен, если бы ответы учли и это тоже :

Есть ли проблемы с использованием cat myfile | grep -v mypattern | bash -c 'rm myfile; cat> myfile '?

0
13.04.2017, 15:36
2 ответа

ONE DOES NOT SIMPLE OVERWRATE A FILE WITH THE PROCESSED VALUE

Проблема в том, что вы не можете гарантировать, что будет выполнено первым. Поэтому вам нужно отложить отключение и запись в файл до тех пор, пока вы не будете абсолютно уверены, что файл открыт для чтения.

Это буферизует файл в ОЗУ перед его записью.

cat foo | perl -e 'undef $/; @out=<>; open WRT,">",shift; print WRT @out' foo

Преимущество: сохраняет права доступа к foo. В случае прерывания вы не потеряли исходный файл foo.

Недостаток: foo должен умещаться в ОЗУ.

Это откроет файл для чтения, удалит его и cat из него. Параллельно он ждет, пока файл исчезнет, ​​а когда он исчезнет , перейдет к нему .

(rm foo; cat) < foo | (perl -e 'while(-e "foo"){}'; cat >foo)

Преимущество: Краткое. Работает с файлами размером больше ОЗУ.

Недостаток: foo исчезает при запуске.

(mv foo bar; cat) < foo | (perl -e 'while(-e "foo"){}'; cat >foo && rm bar)

Преимущество: работает с файлами, размер которых превышает размер ОЗУ. В случае неудачи foo сохраняется в качестве резервной копии в bar.

1
28.01.2020, 02:35

Вы не можете просто сделать это, потому что команда tee перезаписывает файл, делая его короче (возможно) и удаляя cat возможность чтения данных, которые были в файле.

Если бы вы могли убедиться, что программы, такие как tee , открывали новый файл, и , если оболочка гарантировала, что cat открывает свой сначала скопируйте, затем вы можете скопировать из старого (фактически удаленного) файла в новый. Но есть много «если» и мало гарантий.

Вы можете предположить, например, что cat будет запускаться первым, а tee позже (когда это необходимо для сбора данных). Но оболочка запускает обе, и если tee не ожидает ввода до запуска cat , запись может завершиться ошибкой (поскольку никто не ждет, и эти байты имеют некуда идти). Проще заставить процессы ждать чтения , чем записи .

1
28.01.2020, 02:35

Теги

Похожие вопросы