Я сталкиваюсь со странным поведением, когда пытаюсь открыть man-страницу в macOS. Например, страница руководства Bash явно содержит строку NAME
:
$ man bash | head -5 | tail -1
NAME
И если я grep для name
я получаю результаты, но если я grep для NAME
я не:
$ man bash | grep 'NAME'
$ man bash | grep NAME
Я пробовал другие прописные слова, которые я знаю, там, и поиск SHELL
ничего не дает, тогда как поиск BASH
результатов дает.
Что тут происходит?
Обновление : спасибо за все ответы! Я думал, что стоит добавить контекст, в котором я столкнулся с этим. Я хотел написать функцию bash для переноса, man
и в тех случаях, когда я пытался найти справочную страницу для встроенной оболочки, переходил к соответствующему разделу справочной страницы Bash. Возможно, есть лучший способ, но вот что я получил в настоящее время:
man () {
case "$(type -t "$1")" in
builtin)
local pattern="^ *$1"
if bashdoc_match "$pattern \+[-[]"; then
command man bash | less --pattern="$pattern +[-[]"
elif bashdoc_match "$pattern\b"; then
command man bash | less --pattern="$pattern[[:>:]]"
else
command man bash
fi
;;
keyword)
command man bash | less --hilite-search --pattern='^SHELL GRAMMAR$'
;;
*)
command man "$@"
;;
esac
}
bashdoc_match() {
command man bash | col -b | grep -l "$1" > /dev/null
}
man bash | grep NAME
работает как положено.help
чтобы получить ее информацию.help
результаты слишком большими. Проверьтеhelp complete
противcomplete
раздела вman bash
, например.Ответы:
Если вы добавите
| sed -n l
к этойtail
команде, чтобы показать непечатаемые символы, вы, вероятно, увидите что-то вроде:То есть каждый символ записывается как
X
BackspaceX
. На современных терминалах символ заканчивается написанием над собой (так как Backspace или BS, он\b
же aka^H
- это символ, который перемещает курсор на один столбец влево) без разницы. Но в древних телетайпах это приводило к тому, что персонаж выделялся жирным шрифтом, поскольку чернил в два раза больше.Тем не менее, пейджеры любят
more
/less
действительно понимают, что формат означает жирный шрифт, так что это по-прежнему то,roff
что выводит жирный текстНекоторые реализации man вызывают
roff
таким образом, что эти последовательности не используются (или внутренне вызываютcol -b -p -x
для их удаления, как в случаеman-db
реализации (если не установленаMAN_KEEP_FORMATTING
переменная окружения)), и не вызывают пейджер, когда обнаруживают вывод не собирается в терминал (такman bash | grep NAME
будет работать там), но не ваш.Вы можете использовать
col -b
для удаления этих последовательностей (есть и другие типы (_
BSX
), а также для подчеркивания).Для систем, использующих GNU
roff
(например, GNU или FreeBSD), вы можете избежать использования этих последовательностей в первую очередь, убедившись, что-c -b -u
опции переданыgrotty
, например, убедившись, что-P-cbu
опции переданыgroff
.Например, путем создания сценария-оболочки, который
groff
содержит:Что вы поставили перед / usr / bin / groff
$PATH
.С macOS '
man
(также с использованием GNUroff
) вы можете создатьman-no-overstrike.conf
с:И называть
man
как:Тем не менее, в GNU
roff
, если вы установитеGROFF_SGR
переменную среды (или не установитеGROFF_NO_SGR
переменную в зависимости от того, как были установлены значения по умолчанию во время компиляции), тогдаgrotty
(если она не была передана-c
), вместо этого будут использоваться escape-последовательности терминала ANSI SGR из этих трюков BS для атрибутов персонажа.less
понять их при вызове с-R
опцией.Человек FreeBSD вызывает
grotty
с-c
опцией, если вы не запрашиваете цвета , устанавливая переменную MANCOLOR (в этом случае-c
она не передаетсяgrotty
иgrotty
возвращается к использованию по умолчанию escape-последовательностей ANSI SGR).будет работать там.
В Debian GROFF_SGR не используется по умолчанию. Если вы делаете:
однако, поскольку
man
stdout не является терминалом, он также берет на себя передачуGROFF_NO_SGR
переменной вgrotty
(я полагаю, поэтому он может использоватьcol -bpx
для удаления последовательностей BS, посколькуcol
не знает, как удалять последовательности SGR, даже если он все еще делает это сMAN_KEEP_FORMATTING
) который отменяет нашGROFF_SGR
. Вы можете сделать вместо этого:(в терминале) иметь escape-последовательности SGR.
В этот раз вы заметите, что некоторые из этих ИМЯ отображаются на терминале жирным шрифтом (и на
less -R
пейджере). Если вы передадите вывод вsed -n l
(MANPAGER='sed -n /NAME/l'
), вы увидите что-то вроде:Где
\e[1m
последовательность включения жирного шрифта в ANSI-совместимых терминалах и\e[0m
последовательность для возврата всех атрибутов SGR к значениям по умолчанию.Этот текст
grep NAME
работает так же, как этот текстNAME
, но у вас все еще могут быть проблемы, если вы ищете текст, где только его части выделены жирным шрифтом / подчеркиванием ...источник
sed -n l
как заменуod
.Если вы посмотрите на любую страницу руководства, вы заметите, что заголовки выделены жирным шрифтом. Это достигается путем форматирования их с помощью управляющих символов. Чтобы быть в состоянии,
grep
как вы хотите, они должны быть удалены.col
Утилита может использоваться для этого:-b
Вариант имеет следующее описание на OpenBSD :В
col
руководстве по Linux (для Ubuntu) нет последнего предложения (но оно работает точно так же).В Linux
MAN_KEEP_FORMATTING
также может помочь сброс переменной среды (или установка ее в пустую строку), которая позволит вамgrep
не передавать выходные данныеman
черезcol -b
.источник
NAME
по bash простоNAME
нет\b
.MAN_KEEP_FORMATTING
переменная работает точно так же, как вы говорите. Я просто хотел отметить, что это не всегда так.