/ dev / zero
- это пример «специального файла», в частности, «узла устройства». Обычно они создаются в процессе установки дистрибутива, но вы можете полностью создать их сами, если хотите.
Если вы спросите ls
о / dev / zero
:
# ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5 Nov 5 09:34 /dev/zero
«c» в начале говорит вам, что это «символьное устройство»; другой тип - «блочное устройство» (печатается ls
как «b»). Грубо говоря, устройства с произвольным доступом, такие как жесткие диски, обычно являются блочными устройствами, в то время как последовательные устройства, такие как ленточные накопители или звуковая карта, обычно являются символьными устройствами.
Часть «1, 5» - это «основной номер устройства» и «дополнительный номер устройства».
Имея эту информацию, мы можем использовать команду mknod
для создания нашего собственного узла устройства:
# mknod foobar c 1 5
Это создает новый файл с именем foobar
в текущей папке, который делает в точности то же самое, что и / dev / zero
. (Вы, конечно, можете установить для него разные разрешения, если хотите.) Весь этот «файл» на самом деле содержит три элемента, указанные выше: тип устройства, старший номер, младший номер. Вы можете использовать ls
, чтобы найти коды для других устройств и воссоздать их тоже. Когда вам надоест, просто используйте rm
, чтобы удалить только что созданные узлы устройств.
В основном старший номер сообщает ядру Linux, с каким драйвером устройства разговаривать, а младший номер сообщает драйверу устройства, о каком устройстве вы говорите. (Например, у вас, вероятно, один контроллер SATA, но, возможно, к нему подключено несколько жестких дисков.)
Если вы хотите изобрести новые устройства, которые делают что-то новое ... ну, вам нужно отредактировать исходный код ядра Linux и скомпилировать собственное ядро. Так что не будем этого делать! :-) Но вы можете добавлять файлы устройств, которые дублируют уже имеющиеся у вас. Автоматическая система, такая как udev, в основном просто отслеживает события устройства и автоматически вызывает mknod
/ rm
. Ничего более волшебного, чем это.
Есть еще другие типы специальных файлов:
Linux рассматривает каталог как особый вид файла. (Обычно вы не можете напрямую открыть каталог, но если бы вы могли, вы бы обнаружили, что это обычный файл, который содержит данные в специальном формате и сообщает ядру, где найти все файлы в этом каталоге.)
Символьная ссылка - это особый файл. (Но жесткой ссылки нет.) Вы можете создавать символические ссылки с помощью команды ln -s
. (Посмотрите справочную страницу для этого.)
Также есть вещь, называемая «именованный канал» или «FIFO» (очередь «первым пришел - первым вышел»). Вы можете создать его с помощью mkfifo
. FIFO - это волшебный файл, который может быть открыт двумя программами одновременно - одна чтение, одна запись. Когда это происходит, он работает как обычная оболочка. Но вы можете запускать каждую программу отдельно ...
Файл, который ни в коем случае не является «особенным», называется «обычным файлом». Иногда вы можете встретить упоминание об этом в документации Unix. Вот что это значит; файл, который не является узлом устройства, символической ссылкой или чем-то еще. Обычный, повседневный файл без каких-либо магических свойств.
Одно верно, другое нет.
du -sh *
(должно быть du -sh -- *
, чтобы избежать проблем с именами файлов, начинающимися с-
)
полагается на оболочку для расширения шара *
; du
видит все не -скрытые файлы и каталоги в текущем каталоге как отдельные аргументы. Это правильно обрабатывает специальные символы.
ls | xargs du -sh
полагается на xargs
для обработки вывода ls
. xargs
разделяет ввод на пробелы (по крайней мере пробел, табуляция и новая строка, больше с некоторыми реализациями ), также понимает некоторую форму кавычек и запускаетdu
(один (даже для пустого ввода¹ )или более вызовов )с каждой отдельной строкой, разделенной пробелами -, в качестве отдельных аргументов.
Оба кажутся эквивалентными, если ваш текущий каталог не содержит файлов с пробелами, одинарными кавычками, двойными кавычками или символами обратной косой черты в их именах, и если файлов достаточно (, но хотя бы один ), который xargs
выполняет только один du
вызов, но это не так.
С точки зрения эффективности, du -sh *
использует один процесс, ls | xargs du -sh
использует как минимум три. Существует один сценарий, в котором конвейерный подход будет работать, в то время как glob не будет :, если у вас слишком много файлов в текущем каталоге, оболочка не сможет запустить du
со всеми их именами за один раз., но xargs
будет выполняться du
столько раз, сколько необходимо, чтобы охватить все файлы, и в этом случае вы увидите несколько строк, а файлы с более чем одной жесткой ссылкой могут быть учтены несколько раз.
См. также Почему *не *parse `ls `?
¹ Если в текущем каталоге нет скрытого файла, отличного от -, du -sh -- *
либо завершится с ошибкой вашей оболочки, либо с некоторыми оболочками, такими как bash
, запустите du
с литералом *
в качестве аргумента и du
будет жаловаться на то, что этот файл *
не существует.
В то время как с ls | xargs du -sh --
, большинство xargs
реализаций (, за исключением некоторых BSD ), будут запускаться du
без аргументов и, таким образом, указывать использование диска в текущем каталоге (, а также включая диск использование самого файла каталога и всех скрытых файлов и каталогов в нем)
В первом случае оболочка раскрывает *
в список совпадающих имен файлов и передает их в качестве аргументов команде du
. Во втором случае оболочка запускает два процесса(ls
и xargs
), соединенных через конвейер. ls
печатает имена файлов, а xargs
читает их, затем запускает команду du
. Итак, вторая версия выполняет 3 команды, первая — только одну. Есть некоторые потенциальные различия:
ls
может указывать файлы в другом порядке ls
может даже указывать больше или меньше файлов, (не уверен в этом, хотя)xargs
получает больше имен файлов, чем может быть передано в качестве аргументов, он будет выполнять du
несколько раз