Что означает / dev / null в сценарии оболочки?

Я начал изучать скрипты bash, используя это руководство: http://www.tldp.org/LDP/abs/abs-guide.pdf

Однако я застрял в первом скрипте:

cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Log files cleaned up."

Что делают строки 2 и 3 в Ubuntu (я понимаю cat)? Это только для других дистрибутивов Linux? После запуска этого скрипта с правами root, я получаю Log files cleaned up.. Но /var/log все еще содержит все файлы.

1
задан 23 August 2014 в 20:42

4 ответа

Предполагая, что команды выполнены успешно, /var/log/messages и /var/log/wtmp все еще существуют, но теперь пустые.

Перенаправление оболочки

> - это оператор перенаправления, реализуемый оболочкой , Его синтаксис:

command > file

Это переназначает стандартный вывод blank на file.

file также может быть узлом устройства. Если file не существует, он создается как обычный файл. Если file уже существует как обычный файл и не пуст, он перезаписывается. Обычно это происходит в командах, которые вы запускали, где вы перенаправили вывод cat /dev/null на messages и wtmp. Если file уже существует как символическая ссылка, используется цель ссылки. Если file уже существует как каталог, вы получите сообщение об ошибке, например bash: file: Is a directory.

(Конечно, эти операции могут завершиться неудачно по другим причинам, таким как отсутствие стандартного вывода или ошибка файловой системы.)

Перенаправление >> оператор аналогичен, но file до конца непустых правильных файлов вместо перезаписи их содержимого. (Другим оператором перенаправления является <. [F21] использует file как стандартный вход command.)

Устройство null

/dev/null является

file также может быть узлом устройства. Запись на /dev/null ничего не делает: данные, записанные на это устройство, просто «исчезают».

Часто стандартный вывод команды отключается, перенаправляя ее на /dev/null, и это, возможно, наиболее распространенное использование устройства null в сценариях оболочки:

command > /dev/null
[!d37 ]

Вы используете /dev/null по-другому. cat /dev/null выводит «содержимое» в /dev/null, т. е. его вывод пуст. > messages (или > wtmp) заставляет этот пустой вывод перенаправляться в файл с правой стороны оператора >.

Поскольку messages и wtmp являются обычными файлами (скорее чем, например, узлы устройства), они превращаются в пустые файлы (т. е. опустели).

Вы можете использовать любую команду, которая ничего не делает и не выводит вывод слева от >. [ ! d40]

Альтернативный способ очистки этих файлов должен выполняться:

echo -n > messages
echo -n > wtmp

Требуется флаг -n, или echo записывает стандартный вход [!d30 ].

(Это перезаписывает . И я считаю, что по умолчанию sh в каждом дистрибутиве GNU / Linux и другой Unix-подобной системе, широко используемой сегодня, поддерживает флаг -n в своем echo встроенном. Но jlliagre прав, что echo -n следует избегать для действительно портативного сценария оболочки, поскольку он не должен работать. Возможно, именно поэтому руководство, которое вы используете, учит cat /dev/null.

Способ echo -n эквивалентен по своим эффектам, но, возможно, является лучшим решением, i n что это проще. cat /dev/null > file открывает три «файла»:

Запись на /dev/null ничего не делает: данные, записанные на этом устройстве, просто «исчезают». Если file file

Напротив, echo -n > file открывается только . ([ f55] - это встроенная оболочка).

Хотя этого следует ожидать, чтобы повысить производительность, это не принесло пользы - не тогда, когда вы просто выполняете пару этих команд вручную. Вместо этого преимущество в том, что легче понять, что происходит.

Перенаправление и тривиальная (пустая / пустая) команда.

Как указал jlliagre (см. Также jlliagre прав ), это можно укоротить, просто опуская команду слева от > вообще. Хотя вы не можете опустить правильную сторону выражения > или >>, пустая команда действительна (это команда, которую вы запускаете, когда вы просто нажимаете клавишу «Ввод» в пустой строке) и, опуская левую сторону, (! d61) file

Перенаправление из пустой команды (а не из [ f59] или echo -n) выглядит так:

> messages
> wtmp

42
ответ дан 24 May 2018 в 04:24
  • 1
    Вау! Спасибо за подробное объяснение. – rishiag 22 August 2014 в 23:09
  • 2
    Вы можете пойти дальше и заменить бесполезный echo -n на : или просто ничего, учитывая тот факт, что команда ничего не делает. – jlliagre 23 August 2014 в 14:18
  • 3
    Вместо echo -n я бы рекомендовал вам использовать truncate - с помощью команды, предназначенной для этой цели, по моему варианту, немного яснее будущим читателям скрипта. – Boris the Spider 23 August 2014 в 15:42
  • 4
    @BoristheSpider Я получаю вашу точку зрения на удобочитаемость, но оболочка может сделать это более простым способом с пустым перенаправлением. – jlliagre 23 August 2014 в 18:22
  • 5
    @jlliagre. Вы правы: хотя я думал предложить echo -n > messages, поскольку он самодокументирован, возможно, еще лучше и более поучительно использовать > messages, что эквивалентно. Спасибо за то, что вы указали это - я расширил свой ответ, чтобы охватить этот вариант. (: > messages тоже в порядке, хотя лично мне это не особенно нравится - это имеет тот же смысл , что true > messages, true также является встроенной оболочкой. Если я собираюсь перенаправить с именованной команды, echo -n является самодокументированным, поскольку его цель лежит на его выходе .) – Eliah Kagan 23 August 2014 в 20:33

Как уже было сказано, эти две строки очищают содержимое файлов /var/log/messages и /var/log/wtmp или создают их в маловероятном случае, когда они еще не существуют.

Однако они основанный на хорошо зарекомендовавшей себя городской легенде, которая дает /dev/null «паранормальные» способности.

На самом деле это не так, cat /dev/null - это отходы клавиш, времени и циклов процессора, поскольку он ничего не выводит. Ответ Элиа Кагана предлагает лучший подход, который использует echo -n. Это лучше, но не переносимо для некоторых оболочек / операционных систем, где оно может помещать строку [-n "в эти файлы.

Вы можете пойти дальше и заменить эти команды портативным и простым: [!d3 ]

cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."

С большинством оболочек (но не с csh) вы можете пойти еще дальше и удалить команду no-op ':':

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
10
ответ дан 24 May 2018 в 04:24
  • 1
    Я вижу преимущество перенаправления из : (а не из ничего) в том, что он будет работать с оболочками не-борновского типа, такими как csh / tcsh. Существуют ли также оболочки Bourne-стиля, которые не будут перенаправлять stdout из пустой команды? – Eliah Kagan 23 August 2014 в 21:16
  • 2
    @EliahKagan Нет оболочки Bourne, о которой я знаю, не будет перенаправлять stdout из пустой команды. Это уже имело место с оригинальной оболочкой Bourne Unix версии 7 (1979). – jlliagre 24 August 2014 в 00:30

> выводит оператор перенаправления. Он перенаправляет вывод команды в файл, указанный после него, вместо стандартного устройства вывода, усечения или перезаписи содержимого файла.

, например ls -l > demo.txt. После выполнения этой команды «demo.txt» будет содержать команду ls -l.

Теперь следующая вещь - это /dev/null. [F6] - это нулевой файл Is, это специальный файл, который не содержит ничего.

Поэтому, когда вы выполняете команды

cat /dev/null > messages
cat /dev/null > wtmp

, он очищает содержимое файлов «сообщения» и «wtmp» путем перезаписи символом EOF (конец файла). [ ! d4]

Итак, вы не очищаете свой каталог /var/log, но вы очищаете содержимое этих двух файлов.

5
ответ дан 24 May 2018 в 04:24

/ dev / null - как черная дыра. Записи, сделанные в / dev / null, отбрасываются. В этом скрипте они используют / dev / null, чтобы очистить файл журнала сообщений.

В противном случае они могли бы просто использоваться.

 > /var/log/messages.

Есть другие способы опорожнения содержимого файла

Как.

     truncate  -s  0  /var/log/messages
     cp  /dev/null  /var/log/messages

Но использование «>» или «/ dev / null» является эффективным способом.

0
ответ дан 24 May 2018 в 04:24

Другие вопросы по тегам:

Похожие вопросы: