Чи слід використовувати одно- або двокутні дужки для переадресації на / dev / null?


18

Більшість відповідей тут [ 1 ] [ 2 ] [ 3 ] використовують однокутний кронштейн для переадресації на / dev / null, наприклад:

command > /dev/null

Але додавання до / dev / null також працює:

command >> /dev/null

За винятком зайвого персонажа, чи є причина не робити цього? Чи будь-який з цих "приємніших" до основної реалізації / dev / null?

Edit: відкрито (2) сторінка керівництво каже lseek викликається перед кожним записом в файл в режимі додавання:

O_APPEND
Файл відкривається в режимі додавання. Перед кожним записом (2) зміщення файлу розміщується в кінці файлу, як би з lseek (2). Модифікація зміщення файлу та операція запису виконуються як один атомний крок.

що змушує мене думати, що за використання може бути невеликий штраф за продуктивність >>. Але з іншого боку, обрізання / dev / null видається невизначеною операцією відповідно до цього документа:

O_TRUNC
Якщо файл вже існує і є звичайним файлом, а режим доступу дозволяє записувати (тобто є O_RDWR або O_WRONLY), він буде усічений на довжину 0. Якщо файл - файл FIFO або термінальний пристрій, прапор O_TRUNC ігнорується. В іншому випадку ефект O_TRUNC не визначений.

і специфікація POSIX говорить , що слід усікати >існуючий файл , але O_TRUNC визначається реалізацією для файлів пристроїв, і немає слова про те, як / dev / null повинен відповідати на усічення .

Отже, чи справді не визначено обрізання / dev / null? І чи впливають дзвінки lseek на продуктивність запису?

Відповіді:


27

За визначенням /dev/nullопускається все, що написано на ньому , тому не має значення, пишете ви в режимі додавання чи ні, все відкидається. Оскільки він не зберігає дані, насправді нічого додати не можна.

Отже, врешті-решт, писати > /dev/nullодним >знаком просто коротше .

Щодо редагованого додатку:

Відкрита (2) сторінка повідомляє, що lseek викликається перед кожним записом у файл у режимі додавання.

Якщо ви уважно прочитаєте, ви побачите, що він говорить (моє наголос):

зміщення файлу розміщується в кінці файлу, як би з lseek (2)

Це означає, що насправді не потрібно викликати lseekсистемний виклик, і ефект також не є абсолютно однаковим: дзвінок lseek(fd, SEEK_END, 0); write(fd, buf, size);без O_APPENDне є тим самим, як запис у режимі додавання, оскільки при окремих викликах інший процес може записати на файл між системними дзвінками, переносячи додані дані. У режимі додавання цього не відбувається (за винятком NFS, який не підтримує реальний режим додавання ).

Текст в стандарті не згадується lseekв цій точці, тільки що запис буде йти до кінця файлу.

Отже, чи справді не визначено обрізання / dev / null?

Судячи з Писання, на яке Ви посилаєтесь, очевидно, це визначено реалізацією. Це означає, що будь-яка розумна реалізація буде робити так само, як і з трубами та TTY, а саме, нічого. Божевільна реалізація може зробити щось інше, і, можливо, усічення може означати щось розумне у випадку якогось іншого файлу пристрою.

І чи впливають дзвінки lseek на продуктивність запису?

Перевірте це. Це єдиний спосіб точно знати в даній системі. Або прочитайте джерело, щоб побачити, де режим додавання змінює поведінку, якщо де є.


-3

Якщо вам потрібна ефективність, використовуйте command >&-замість цього. Це закриває дескриптор файлів, а не перенаправляє його, тому не витрачається час взагалі на написання речей.


3
Не закривайте потоки менше 3. Це псевдоніми дескрипторів std * з дескрипторами випадкових файлів; потенційно з катастрофічними результатами.
Джошуа

7
Якщо ви просто закриєте дескриптор файлів, програма буде отримувати помилки під час кожного виклику при записі, що, ймовірно, призводить до дратівливих повідомлень про помилки та, можливо, до завершення програми перед завершенням завдання.
ilkkachu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.