Назад | Перейти на главную страницу

Шаблон grep интерпретируется по-разному в двух разных системах с одинаковой версией grep

Мы производим Linux-устройства для центров обработки данных, и все они используют Fedora, установленную в рамках одного процесса кикстарта. Существуют разные версии оборудования, некоторые с жесткими дисками IDE и некоторые SCSI, поэтому файловые системы могут находиться в / dev / sdaN или / dev / hdaN.

У нас есть веб-интерфейс для этих устройств, который показывает использование диска, которое создается с помощью «df | grep / dev / * da». Обычно это работает для обеих версий оборудования, давая следующий результат:

/dev/sda2              5952284   3507816   2137228  63% /
/dev/sda5             67670876   9128796  55049152  15% /data
/dev/sda1               101086     11976     83891  13% /boot

Однако для одной машины мы получаем следующий результат от этой команды:

Binary file /dev/sda matches

Кажется, что его файлы grep соответствуют / dev / * da по неизвестному шаблону по какой-то причине, только в этом поле, которое, по-видимому, идентично версии grep, пакетам, ядру и оборудованию. Я изменил шаблон grep на "/dev/.da", и все работает, как ожидалось, в этом неприятном окне, но мне неприятно не знать, почему это происходит. У кого-нибудь есть идеи? Или, возможно, попробовать другие тесты?

Вероятно, машина, возвращающая Binary file... сообщение имеет более одного диска, возможно, привод компакт-дисков или что-то в этом роде.

Что происходит, так это то, что если вы не защитите шаблон, он будет расширен оболочкой. Это означает, что

grep /dev/*da

... расширяется до

grep /dev/hda /dev/sda

... что означает, что нужно выполнить команду grep, заглянуть в файл / dev / sda и вернуть все строки, соответствующие тексту '/ dev / hda'.

Вам нужно защитить узор, например

grep '/dev/.da'

... чтобы оболочка не расширяла его.

Вы можете подтвердить это на машине-нарушителе, набрав

ls /dev/*da

Я думаю, проблема в том, как оболочка отправляет '/ dev / * da' в grep. Пытаться

echo /dev/*da 

в обеих системах.

В любом случае, я думаю, что правильной версией является /dev/.da, потому что для grep * это означает «Предыдущий элемент будет соответствовать ноль или более раз».

# echo -e '#!/bin/sh\ndf | grep /dev/*da' > df.sh
# sh -x df.sh 
+ df
+ grep /dev/hda /dev/sda
Binary file /dev/sda matches

man grep

   -a, --text
          Process a binary file as if it were text; this is equivalent to the --binary-files=text option.

   --binary-files=TYPE
          If the first few bytes of a file indicate that the file contains binary data, assume that the file
          is  of type TYPE.  By default, TYPE is binary, and grep normally outputs either a one-line message
          saying that a binary file matches, or no message if there is no match.  If TYPE is  without-match,
          grep  assumes  that a binary file does not match; this is equivalent to the -I option.  If TYPE is
          text, grep processes a binary file as if it were text;  this  is  equivalent  to  the  -a  option.
          Warning:  grep  --binary-files=text might output binary garbage, which can have nasty side effects
          if the output is a terminal and if the terminal driver interprets some of it as commands.