Відповіді:
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