Ответы:
cat /dev/null > file.txt
это бесполезно использование кошки .
В основном cat /dev/null
просто cat
ничего не выводится. Да, это работает, но многие его осуждают, потому что это приводит к вызову внешнего процесса, в котором нет необходимости.
Это одна из тех вещей, которая распространена просто потому, что она распространена.
Использование just > file.txt
будет работать на большинстве оболочек, но оно не полностью переносимо. Если вы хотите полностью портативный, следующие варианты являются хорошими:
true > file.txt
: > file.txt
Оба :
и не true
выводят данных, и являются встроенными оболочками (тогда cat
как это внешняя утилита), таким образом, они легче и более «правильны».
Обновить:
Как упомянул Тайлер в своем комментарии, есть также >| file.txt
синтаксис.
У большинства оболочек есть настройка, которая не позволяет им обрезать существующий файл с помощью >
. Вы должны использовать >|
вместо этого. Это сделано для предотвращения человеческих ошибок, когда вы действительно хотели добавить >>
. Вы можете включить поведение с помощью set -C
.
Итак, с этим, я думаю, самый простой, самый правильный и переносимый метод усечения файла будет:
:>| file.txt
:
также обязывает @kojiro быть встроенным, и фактически отличается от true
того, что считается «специальным» встроенным .
>| file
является более явным усечением.
true
не обязательно быть встроенным, и это традиционно не было. :
построен во всех снарядах семьи Борн. :
это специальная встроенная функция для POSIX (поэтому : > file
она выйдет из оболочки, например, если file
не может быть открыта для записи в оболочках POSIX) и true
не является. POSIX даже упоминает, что это :
может быть более эффективным, чем true
в некоторых системах.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Заметки:
sh
или ksh
эмуляции, для перенаправлений без команды в zsh предполагается команда по умолчанию (в cat
противном случае это пейджер только для перенаправления stdin ), которая может быть настроена с помощью переменных NULLCMD и READNULLCMD. Это вдохновлено от аналогичной функции в(t)csh
:
в UnixV7, поскольку :
интерпретировались на полпути между лидером комментария и пустой командой. Позже они были и, как и для всех встроенных, если перенаправление не удается, что выходит из оболочки.:
и, eval
будучи специальными встроенными модулями, в случае сбоя перенаправления, он выходит из оболочки ( bash
только в режиме POSIX).(t)csh
что это определяет нулевую метку (для goto
), так что goto ''
там будет ответвление. Если перенаправление не удается, это выходит из оболочки.$PATH
( как :
правило , не является, true
, cat
, cp
и как printf
правило , не являются (POSIX требует от них)).file
это символическая ссылка на несуществующий файл, некоторые cp
реализации, такие как GNU, откажутся создавать его.(этот раздел очень субъективен)
> file
, Это >
слишком похоже на подсказку или комментарий. Кроме того, вопрос, который я задам, читая этот вопрос (и большинство оболочек будут жаловаться на то же самое), заключается в том, какой именно вывод вы перенаправляете? ,: > file
, :
известен как команда no-op. Так что сразу читается как генерация пустого файла. Однако и здесь это :
легко можно пропустить и / или рассматривать как подсказку.true > file
: что имеет логическое отношение к перенаправлению или содержимому файла? Что здесь подразумевается? это первое, что приходит мне в голову, когда я читаю это.cat /dev/null > file
, Объединить /dev/null
в file
? cat
которые часто видели , как команда , чтобы сбросить содержимое файла, который все еще может иметь смысл: сбросить содержимое в пустой файл вfile
, немного как свернутой способ сказать , cp /dev/null file
но все - таки понятно.cp /dev/null file
, Копирует содержимое пустого файла в file
. Имеет смысл, хотя кто - то , не зная , как cp
это означало , чтобы сделать по умолчанию может подумать , что вы пытаетесь сделать file
на null
устройство , а также.eval > file
или eval '' > file
. Ничего не запускается и перенаправляет вывод в file
. Имеет смысл для меня. Странно, что это не распространенная идиома.printf '' > file
: явно ничего не печатает в файл. Тот, который имеет больше всего смысла для меня.Разница будет в том, будем ли мы использовать встроенную оболочку или нет. Если нет, процесс должен быть разветвлен, команда загружена и выполнена.
eval
гарантированно будет построен во всех снарядах. :
встроен везде, где он доступен (любит Bourne / csh). true
встроен только в Bourne-подобные оболочки.
printf
встроен в большинство современных борноподобных оболочек и fish
.
cp
и cat
вообще не являются встроенными.
Теперь cp /dev/null file
не вызывает перенаправления оболочки, поэтому такие вещи, как:
find . -exec cp /dev/null {} \;
будут более эффективными, чем:
find . -exec sh -c '> "$1"' sh {} \;
(хотя не обязательно чем:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
).
Лично я использую : > file
в оболочках типа Борна, и в эти дни я не использую ничего, кроме оболочек типа Борна.
dd of=file count=0
?
dd
(как минимум в Solaris 10) count=0
игнорируется. dd if=/dev/null of=file
будет более портативным. В любом случае, это не зависит от оболочки.
cp /dev/null file
, верно?
cp /dev/null file
это распространенная идиома. Я ограничиваюсь тем, что дело не в перечислении всех возможных путей.
Возможно, вы захотите посмотреть truncate
, что делает именно это: урезать файл.
Например:
truncate --size 0 file.txt
Это, вероятно, медленнее, чем при использовании true > file.txt
.
Однако я хочу сказать следующее: truncate
предназначен для усечения файлов, а использование> имеет побочный эффект от усечения файла.
truncate
будут доступны, но ни библиотеки C, >
ни unistd
библиотеки не будут доступны?
truncate
является утилитой FreeBSD, сравнительно недавно (2008 г.) добавленной в GNU coreutils (хотя --size
стиль длинных опций GNU специфичен для GNU), поэтому она недоступна в системах, отличных от GNU или FreeBSD, и недоступна в более старых системах GNU, Я бы не сказал, что он портативный. cp /dev/null file
будет работать без перенаправления оболочки и будет более переносимым.
Ответ немного зависит от того file.txt
, что есть, и как процесс записи в него!
Я приведу пример общего использования: у вас есть растущий файл журнала file.txt
, и вы хотите повернуть его.
Поэтому вы копируете, например, file.txt
в file.txt.save
, а затем усекаете file.txt
.
В этом случае, если файл не открывается another_process
(например: это another_process
может быть программа, выводящая в этот файл, например, программа, регистрирующая что-то), тогда ваши 2 предложения эквивалентны, и оба работают хорошо (но второе предпочтительнее, чем first "cat / dev / null> file.txt" - это бесполезное использование Cat, а также открывает и читает / dev / null).
Но настоящая проблема была бы, если other_process
он все еще активен и все еще имеет открытый дескриптор, идущий к файлу file.txt.
Затем возникают 2 основных случая, в зависимости от того, как был other process
открыт файл:
Если other_process
открыть его обычным способом, дескриптор все равно будет указывать на прежнее место в файле, например, со смещением 1200 байтов. Поэтому следующая запись начнется со смещения 1200, и, таким образом, у вас снова будет файл размером 1200 байт (+ что бы ни писал другой_процесс) с 1200 ведущими нулевыми символами! Не то, что вы хотите , я полагаю.
Если other_process
открыть file.txt
в «режиме добавления», то каждый раз, когда он пишет, указатель будет активно искать в конце файла. Поэтому, когда вы усекаете его, он будет «искать» до байта 0, и у вас не будет плохого побочного эффекта! Это то, что вы хотите (... обычно!)
Обратите внимание, что это означает, что вам необходимо при усечении файла убедиться, что все, кто все other_process
еще пишет в это место, открыли его в режиме «добавления». В противном случае вам нужно будет остановить их other_process
и запустить снова, чтобы они указывали на начало файла, а не на прежнее место.
Ссылки: /programming//a/16720582/1841533 для более ясного объяснения и хорошего короткого примера различия между ведением журнала в обычном режиме и в режиме добавления на /programming//a/984761/1841533
cat /dev/null > file
и a > file
есть a, cat /dev/null
и это не имеет значения для файла.
Мне это нравится, и я часто его использую, потому что он выглядит чище, а не потому, что кто-то случайно нажал клавишу возврата:
echo -n "" > file.txt
Должен быть встроенным тоже?
echo
реализации не поддерживают -n
(и выводили бы -n<SPC><NL>
здесь. printf '' > file.txt
Были бы более переносимыми (по крайней мере, в современных системах / POSIX).