Я підозрюю, чому багато чого стосується бачення / дизайну, який формував Unix (і, отже, Linux), та переваг, що випливають з цього.
Без сумніву, є несуттєва користь від продуктивності, щоб не розгортати зайвий процес, але я думаю, що в цьому є і більше: Early Unix мав метафору "все є файлом", яка має не очевидну, але елегантну перевагу, якщо подивитися це з системної точки зору, а не з сценарію оболонок сценаріїв.
Скажіть, у вас є програма null
командного рядка та /dev/null
вузол пристрою. З точки зору оболонок сценаріїв, foo | null
програма насправді є справді корисною та зручною та foo >/dev/null
потребує трохи більше часу, щоб набрати та може здатися дивним.
Але ось дві вправи:
Давайте реалізуємо програму , null
використовуючи існуючі інструменти Unix і /dev/null
- легко: cat >/dev/null
. Зроблено.
Чи можете ви реалізувати /dev/null
з точки зору null
?
Ви абсолютно праві, що код C для відмови від введення є тривіальним, тому може бути ще не очевидно, чому корисно мати віртуальний файл для виконання завдання.
Поміркуйте: майже кожна мова програмування вже потребує роботи з файлами, дескрипторами файлів та шляхами до файлів, оскільки вони з початку були частиною парадигми Unix "все є файл".
Якщо все, що у вас є, це програми, які пишуть у stdout, ну, програмі не важливо, перенаправляєте їх у віртуальний файл, який проковтує всі записи, або трубу в програму, яка ковтає всі записи.
Тепер, якщо у вас є програми, які беруть шляхи до файлів читання чи запису даних (що це робить більшість програм), - і ви хочете додати до цих програм функцію "пустий ввід" або "відкинути цей вихід" - добре, /dev/null
що це безкоштовно.
Зауважте, що його елегантність полягає в тому, що це зменшує складність коду всіх програм, що беруть участь - для кожного загального, але особливого шаблону, який ваша система може надати як "файл" з фактичним "ім'ям файлу", ваш код може уникнути додавання спеціальної команди -лінійні параметри та спеціальні шляхові коди для обробки.
Хороша інженерія програмного забезпечення часто залежить від того, щоб знайти хороші або "природні" метафори для абстрагування якогось елемента проблеми таким чином, що стає простіше думати, але залишається гнучким , так що ви можете вирішити в основному той самий спектр проблем вищого рівня без необхідності постійно витрачайте час і розумову енергію на повторне втілення в життя рішень тих самих проблем нижчого рівня.
"Все є файлом", здається, є однією з таких метафор для доступу до ресурсів: Ви викликаєте open
заданий шлях у герархічному просторі імен, отримуєте посилання (дескриптор файлу) на об'єкт, і ви можете read
і write
т. Д. На дескриптори файлів. Ваш stdin / stdout / stderr - це також дескриптори файлів, які щойно були попередньо відкриті для вас. Ваші труби - це лише файли та дескриптори файлів, а перенаправлення файлів дозволяє склеїти всі ці частини разом.
Unix досяг успіху настільки ж, як і частково, через те, наскільки добре ці абстракції працювали разом, і /dev/null
це найкраще розуміти як частину цілого.
PS Варто подивитися на версію Unix "все є файлом" і такі речі, як /dev/null
перші кроки до гнучкішого та потужнішого узагальнення метафори, що було реалізовано у багатьох системах, що слідували за цим.
Наприклад, в Unix спеціальні файлоподібні об'єкти, такі як /dev/null
повинні були бути реалізовані в самому ядрі, але виявляється, що досить корисно розкрити функціональність у формі файлу / папки, що з тих пір було створено кілька систем, які забезпечують шлях для програм зробити це.
Однією з перших була операційна система Plan 9, яку створили одні і ті ж люди, які створили Unix. Пізніше GNU Hurd зробив щось подібне зі своїми "перекладачами". Тим часом, Linux в кінцевому підсумку отримав FUSE (який уже розповсюдився на інші основні системи).
cat foo | bar
є значно гіршою (за масштабами), ніжbar <foo
.cat
це тривіальна програма, але навіть тривіальна програма створює витрати (деякі з них характерні для семантики FIFO - оскільки програми не можуть бутиseek()
всередині FIFO, наприклад, програма, яка може бути ефективно реалізована за допомогою пошуку, може зробити набагато дорожчі операції коли йому надано конвеєр; з таким символьним пристроєм, як/dev/null
він може підробляти ці операції, або з реальним файлом він може реалізовувати їх, але FIFO не допускає будь-якого обстеження в контексті).