Как очистить («обрезать») файл в linux, который уже существует и каким-то образом защищен?

113

У меня на сервере есть файл error.log, который мне нужно часто обрезать. У меня есть права доступа к файлу. Открытие файла в vi> удаление всего содержимого> сохранение работает (очевидно). Но когда я попробую следующее

cat /dev/null > error.log

Я получаю сообщение

File already exists.

Очевидно, что на сервере есть какая-то конфигурация, чтобы предотвратить случайное переопределение файлов. Кто-нибудь может сказать, как «обрезать» файл с помощью одной команды?

Сумит Парик
источник
2
Для незащищенного файла работает truncate -s 0 file.
Pramod

Ответы:

158

У вас есть noclobberнабор опций. Ошибка выглядит так, как будто она из csh, поэтому вы должны сделать:

cat /dev/null >! file

Если я ошибаюсь и вы используете bash, вам следует сделать:

cat /dev/null >| file

в bash вы также можете сократить это до:

>| file
R Самуэль Клатчко
источник
вы правы в том, что оболочка является csh. Как ты это узнал?
Sumeet Pareek,
6
@Wikidkaka - на основании сообщения об ошибке. csh в моей системе дает аналогичную File existsошибку, а bash дает совсем другую cannot overwrite existing fileошибку.
R Samuel Klatchko
6
@Jarmund - так как у пользователя не установлено >fileни одного заголовка, не работает.
R Samuel Klatchko
В чем разница между > fileи >| file?
Will
1
@Will - если у вас установлен noclobberпараметр, попытка перенаправления на существующий файл не удалась. Чтобы переопределить конкретное перенаправление, оставив включенным noclobber, вы можете использовать>|
R Samuel Klatchko
71

Вы также можете использовать функцию truncate

$truncate -s0 yourfile

если в разрешении отказано, используйте sudo

$sudo truncate -s0 yourfile

Справка / Руководство: man truncate

протестировано на Ubuntu Linux

Risnandar
источник
1
truncate также затрагивает время модификации файла - в то время как "> file" не затрагивает, если файл не изменился.
dsteinkopf
Он не освобождает дисковое пространство, которое занимает файл. Сначала он показывает 0 байтов. Но когда вы что-то записываете в этот файл, размер файла равен = до усечения + новый размер данных.
Аникет Кулкарни
48

Этого будет достаточно, чтобы установить размер файла равным 0:

> error.log
SIFE
источник
6
на самом деле, это не работает с noclobber (сам тестировал), поэтому в данном случае это НЕ подходящее решение («-bash: error.log: невозможно перезаписать существующий файл»); см. комментарий выше («@Jarmund - поскольку у пользователя не задано ни одного заголовка,> файл не работает.»). Мне просто интересно, какие «умные люди» голосуют за такие заведомо неправильные ответы, как этот ...
9

заслуга моего старшего коллеги в этом:

:> filename

Это не повредит файлы журнала, поэтому вы даже можете использовать его, например, в системном журнале.

Петермольнар
источник
8
Пожалуйста, объясни. Как это работает? Что делает эта нотация?
user31986
2
@ user31986 :- это неэффективная команда (почти комментарий), а затем >перенаправление, как обычно, таким образом, это просто перенаправляет отсутствие вывода команды, которая ничего не делает в файл. Если noclobber включен, вам понадобится :>| filename(bash) (и я предполагаю, что :>! filenameв csh, если csh есть :).
Rhubbarb
4

false | tee fileToTruncate

может также работать

Dodger Web
источник
Это просто глупо. Или, если это полезно, неявно ddвыводить что-либо было бы лучше, чем просто читаемое false?
tripleee
2

Поскольку sudo не работает с перенаправлением > , мне нравится teeкоманда для этой цели

echo "" | sudo tee fileName
sakhunzai
источник
ну, на самом деле это так, как описано как в вопросе, который вы указали, так и здесь выше. "sudo sh -c '> error.log'" ...
это зависит от разрешений на целевой файл error.log, если он уже доступен для записи, нет необходимости в sudo. Я думаю, что другая проблема заключается в том, что вы передаете команду в виде строкового аргумента sh, я не знаю, как это обрабатывается внутри, но это еще один уровень сложности / добавленного перенаправления
sakhunzai
1
На самом деле это не приведет к усечению файла, потому echo ""что добавится новая строка. Вы можете использовать echo -n ""для подавления новой строки
Себ
0

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

Это обязательно будет работать в любом формате:

truncate -s 0 file.txt
user3301460
источник
-4

Вы также можете попробовать:

echo -n > /my/file

Оден
источник
8
Видите ответ, набравший массу голосов? Попробуйте прочитать его, посмотрите вверх noclobberи спросите себя, имеет ли вообще смысл ваш ответ.