Недавно я разговаривал с коллегой, когда он был в своей раковине, когда я увидел, что он делает что-то вроде ls -l | grep asdf*
.
"Почему шар?" Я спросил его. «Я всегда так делаю», - ответил он.
Я не сразу увидел какие-либо проблемы, но все равно чувствовал себя не так. Когда я сам попробовал это позже, я увидел другое поведение:
--> ls -l | grep ls
-rwxr-xr-x 1 root root 22896 Nov 19 2012 false
-rwxr-xr-x 1 root root 105840 Nov 19 2012 ls
-rwxr-xr-x 1 root root 44640 Nov 19 2012 lsblk
-rwxr-xr-x 1 root root 6272 Nov 19 2012 lsmod
-rwxr-xr-x 1 root root 31912 Nov 19 2012 ntfsls
--> ls -l | grep ls*
Binary file lsblk matches
Binary file lsmod matches
Что здесь происходит на земле? Я подумал, что в худшем случае grep будет рассматривать это как регулярное выражение l(s*)
и будет давать мне каждый раз l
, но этот ввод даже не отображается в ls! (Я запускаю это из /bin
).
Что делает grep, когда вы ставите глобус после строки поиска? Должен ли я сказать своему коллеге прекратить делать это в будущем?
Когда Вы делаете grep ls*
, оболочка сначала расширяется ls*
к списку соответствия файлам в текущем каталоге, таким образом, команда становится
ls -l | grep ls lsblk lsmod
В этом случае, grep
будет игнорировать стандартный вход и рассматривать первый аргумент ls
как шаблон, который будет согласован в файлах lsblk
и lsmod
, как если бы Вы ввели grep ls lsblk lsmod
(по-видимому, в /bin
):
$ grep ls lsblk lsmod
Binary file lsblk matches
Binary file lsmod matches
С другой стороны, при отсутствии соответствий шарика в текущем каталоге и оболочка nullglob
опция не установлена, затем ls*
будет оставлен нерасширенным, так, чтобы grep
видит ls*
и соответствия любое соответствие имен файлов l
сопровождаемый нулем или больше s
символы (в основном любое имя файла с l
в нем), например:
$ pwd
/home/steeldriver
$ echo ls*
ls*
(нет никаких файлов, соответствующих шарику оболочки ls*
в моем корневом каталоге); затем
$ ls /bin | grep 'ls*'
bzless
chacl
false
.
.
.
zless
tl; доктор не делает этого
Чтобы быть более безопасным, ваш коллега должен использовать:
ls -l | grep "asdf*"
для обработки конвейерного вывода, используя кавычки, мы пропускаем расширения файла оболочки, поэтому мы говорим, что ищем строки с asd
за ним следует ноль или более f
, лучший вариант использования:
ls -l | grep "asdf.*"
Еще одна вещь, которую стоит упомянуть, это то, что если в текущем каталоге не было ни одного файла, соответствующего шаблону, он будет рассматриваться как это grep
, в большинстве случаев это то, что происходит.
Также обратите внимание, что анализ ls
вывода не очень хорошая вещь, чтобы сделать .