Ответ 1
Сначала продемонстрируем, что head
работает корректно:
$ printf '\xef\xbb\xbf' >file
$ head -c 3 file
$ head -c 3 file | hexdump -C
00000000 ef bb bf |...|
00000003
Теперь создайте рабочую функцию has_bom
. Если ваш grep
поддерживает -P
, то один из вариантов:
$ has_bom() { head -c3 "$1" | LC_ALL=C grep -qP '\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
В настоящее время только GNU grep
поддерживает -P
.
Другой вариант - использовать bash $'...'
:
$ has_bom() { head -c3 "$1" | grep -q $'\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
ksh
и zsh
также поддерживают $'...'
, но эта конструкция не POSIX, а dash
не поддерживает ее.
Примечания:
-
Использование явного
return $?
является необязательным. Функция по умолчанию вернется с кодом завершения последнего запуска команды. -
Я использовал форму POSIX для определения функций. Это эквивалентно форме bash, но дает вам еще одну проблему, с которой вам придется столкнуться, если вам когда-либо понадобится запустить функцию под другой оболочкой.
-
bash принимает использование символа
-
в имени функции, но это противоречивая функция. Я заменил его на_
, который более широко принят. (Подробнее об этой проблеме см. этот ответ.) -
Параметр
-q
дляgrep
делает тихий, что означает, что он по-прежнему устанавливает правильный код выхода, но не отправляет никаких символов в стандартный вывод.