Ответы:
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).