Відповіді:
cat /dev/null > file.txt- марне використання кота .
В основному cat /dev/nullпросто catнічого не виходить. Так, це працює, але багато хто знущається, оскільки це призводить до залучення зовнішнього процесу, який не є необхідним.
Це одна з тих речей, яка є загальною просто тому, що вона є загальною.
Використання просто > file.txtбуде працювати на більшості оболонок, але це не повністю портативно. Якщо ви хочете повністю портативні, такі хороші альтернативи:
true > file.txt
: > file.txt
Як :і trueвихід відсутня, а також оболонки вбудованих функцій ( в той час як catзовнішня корисність), таким чином , вони легше і більш «правильні».
Оновлення:
Як згадував tylerl у своєму коментарі, є і >| file.txtсинтаксис.
Більшість оболонок мають налаштування, які не дозволять їм обрізати існуючий файл через >. Ви повинні використовувати >|замість цього. Це запобігає помилкам людини, коли ви дійсно мали намір додати >>. Ви можете ввімкнути поведінку за допомогою set -C.
Отже, з цим, я думаю, найпростішим, найправильнішим і портативним методом обрізки файлу буде:
:>| file.txt
:також зобов’язаний POSIX бути вбудованим, і він фактично відрізняється 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 передбачається команда за замовчуванням (пейджер для перенаправлення stdin, в catіншому випадку), який може бути налаштований за допомогою змінних 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. Нічого не працює і перенаправляє свій результат на a file. Має сенс для мене. Дивно, що це не звичайна ідіома.printf '' > file: явно нічого не друкує у файл. Той, який має для мене найбільше сенсу.Різниця полягатиме в тому, використовуємо ми вбудовану оболонку чи ні. Якщо ні, процес повинен бути роздвоєним, команда завантажена та виконана.
evalгарантовано будується у всіх оболонках. :вбудований де завгодно (Bourne / csh like). trueпобудований лише у мурашниках Борна.
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буде доступний, але ні >ні unistdбібліотеки C будуть доступні?
truncate- це утиліта FreeBSD, відносно недавно (2008 р.) додана до ядер GNU (хоча --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 пропозиції еквівалентні, і обидві працюють добре (але 2-й вважається кращим як перший "cat / dev / null> file.txt" - це марне використання кота, а також відкривається та читається / dev / null).
Але справжня проблема буде в тому випадку, якщо other_processфункція все ще активна і все ще має відкриту ручку, що переходить до file.txt.
Тоді виникають 2 основні випадки, залежно від того, як other process відкрили файл:
Якщо other_process відкрити його звичайним чином, то ручка все одно буде вказувати на колишнє місце у файлі, наприклад, на зміщення 1200 байт. Наступне записування, таким чином, розпочнеться зі зміщення 1200, і, таким чином, ви знову матимете файл 1200байтів (+ що б не написав other_process) зі 1200 провідними нульовими символами! Я припускаю, що не ви хочете .
Якщо його other_processвідкрити file.txtв "режимі додавання", то кожен раз, коли він пише, вказівник активно прагне до кінця файлу. Тому, коли ви вріжете його, він буде "шукати" до байта 0, і у вас не буде поганого побічного ефекту! Це те, що ти хочеш (... зазвичай!)
Зверніть увагу, що це означає, що вам потрібно, коли ви усікаєте файл, переконатися, що все other_process записи ще записуються до цього місця, відкрили його в режимі "додавання". Інакше вам потрібно буде зупинити їх other_processі запустити їх знову, щоб вони почали вказувати на початок файлу замість колишнього місця розташування.
Посилання: /programming//a/16720582/1841533 для отримання більш чіткого пояснення та прикладного короткого прикладу різниці між нормальним і додаванням журнального режиму за адресою /programming//a/984761/1841533
cat /dev/null > fileі a > file- це, cat /dev/nullі це не має значення для файлу.
Мені це подобається і використовую його часто, тому що він виглядає чистіше, а не як хтось випадково потрапив до клавіші повернення:
echo -n "" > file.txt
Чи повинен бути вбудованим теж?
echoреалізацій не підтримують -n(і -n<SPC><NL>printf '' > file.txt