Хоча це правда , що деякі вбудовані команди оболонок можуть мати убогий показ в повному підпорядкуванні - особливо для тих bash
Певних вбудованих команд , які ви тільки ймовірно, використання в системі GNU (GNU на людях, як правило, не вірять в man
і віддайте перевагу власним info
сторінкам) - переважна більшість утиліт POSIX - вбудовані оболонки чи інше - дуже добре представлені в Посібнику програміста POSIX.
Ось уривок з нижньої частини мого (який, мабуть, триває приблизно man sh
20 сторінок ...)
Всі ті , є й інші , які не йдеться , такі як set
, read
, break
... ну, мені не потрібно , щоб назвати їх усіх. Але зверніть увагу (1P)
на праворуч внизу - воно позначає посібник серії POSIX категорії 1 - це man
сторінки, про які я говорю.
Можливо, вам просто потрібно встановити пакет? Це виглядає перспективно для системи Debian. Хоча help
це корисно, якщо ви зможете його знайти, ви обов'язково отримаєте цю POSIX Programmer's Guide
серію. Це може бути надзвичайно корисно. І це складові сторінки дуже докладно.
Окрім цього, вбудовані оболонки майже завжди перераховані в конкретному розділі посібника з конкретних оболонок. zsh
наприклад, для цього є ціла окрема man
сторінка - (я думаю, що це загальна кількість 8 або 9 окремих zsh
сторінок - включаючи zshall
які величезні.)
Ви можете grep
man
звичайно:
man bash 2>/dev/null |
grep '^[[:blank:]]*read [^`]*[-[]' -A14
read [-ers] [-a aname] [-d delim] [-i text] [-n
nchars] [-N nchars] [-p prompt] [-t timeout] [-u
fd] [name ...]
One line is read from the standard input, or
from the file descriptor fd supplied as an
argument to the -u option, and the first
word is assigned to the first name, the sec‐
ond word to the second name, and so on, with
leftover words and their intervening separa‐
tors assigned to the last name. If there
are fewer words read from the input stream
than names, the remaining names are assigned
empty values. The characters in IFS are
used to split the line into words using the
same rules the shell uses for expansion
... що досить близько до того, що я робив під час пошуку оболонки man
. Але в більшості випадків help
це досить добре bash
.
Я фактично працював над sed
сценарієм, щоб обробляти подібні речі останнім часом. Так я схопив розділ на малюнку вище. Це ще довше, ніж мені подобається, але вдосконалюється - і може бути досить зручно. У своїй нинішній ітерації він досить надійно витягне контекстно-чутливий розділ тексту у відповідності з заголовком розділу або підрозділу на основі [a] шаблону [s], поданого в командному рядку. Він забарвлює вихід і роздруковує до stdout.
Він працює, оцінюючи рівні відступів. Непорожні рядки введення, як правило, ігноруються, але коли він стикається з порожнім рядком, він починає звертати увагу. Він збирає рядки звідти до тих пір, поки не переконається, що поточна послідовність напевно відступає далі, ніж її перший рядок, перш ніж виникає інший порожній рядок, інакше він скидає нитку і чекає наступного порожнього. Якщо тест виявився успішним, він намагається зіставити лінію ведучого з його аргументами командного рядка.
Це означає, що відповідність шаблону відповідності:
heading
match ...
...
...
text...
..і ..
match
text
..але не..
heading
match
match
notmatch
.. або ..
text
match
match
text
more text
Якщо відповідність може бути, вона починає друкувати. Він позбавить провідних пробілів відповідної лінії з усіх рядків, які він друкує - тому незалежно від рівня відступу, він виявив, що рядок на ній друкує так, ніби він знаходиться вгорі. Він буде продовжувати друкувати до тих пір, поки він не зустріне інший рядок на рівній або меншій мірі відступу, ніж його відповідна лінія - тому цілі розділи захоплюються лише збігом заголовка, включаючи будь-який / усі підрозділи, пункти, які вони можуть містити.
Отже, якщо ви попросите його відповідати шаблону, він зробить це лише у певній формі заголовка теми, а також забарвить і надрукує весь текст, який він знайде, у розділі на чолі зі збігом. Нічого не зберігається, окрім цього, окрім відступу першого рядка, - і це може бути дуже швидким та обробляти \n
окремий вхід фактично будь-якого розміру.
Мені знадобилося деякий час, щоб зрозуміти, як повторно вписатись у підзаголовки, наприклад:
Section Heading
Subsection Heading
Але я розібрався в підсумку.
Мені все-таки довелося переробити все заради простоти. Хоча раніше у мене було кілька невеликих циклів, які робили переважно ті самі речі дещо різними способами, щоб відповідати їхньому контексту, змінюючи засоби їх рекурсії, мені вдалося повторити копію більшості кодів. Зараз є дві петлі - один відбиток та один відступ чека. Обидва залежать від одного і того ж тесту - цикл друку починається, коли тест проходить, а цикл відступу переймається, коли він не працює або починається з порожнього рядка.
Весь процес проходить дуже швидко, тому що більшість часу він просто /./d
вибирає будь-яку незаповнену лінію і переходить до наступної - рівномірний результат zshall
миттєвого заповнення екрана. Це не змінилося.
У всякому разі, поки що це дуже корисно. Наприклад, read
щось вище можна зробити так:
mansed bash read
... і отримує цілий блок. Він може приймати будь-які шаблони чи будь-які, або декілька аргументів, хоча перший - це завжди man
сторінка, на якій він повинен шукати. Ось малюнок деяких його результатів після того, як я зробив:
mansed bash read printf
... обидва блоки повертаються цілими. Я часто його використовую так:
mansed ksh '[Cc]ommand.*'
... для яких це цілком корисно. Крім того, отримання SYNOPS[ES]
робить його дуже зручним:
Ось, якщо ви хочете дати йому крутити - я не буду звинувачувати вас, якщо ви цього не зробите.
mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
/\n/!{ /./{ \$p;d
};x; /.*\n/!g;s///;x
:indent
/.*\n\n/{s///;x
};n;\$p;
/^\([^${s}].*\)*$/{s/./ &/;h; b indent
};x; s/.*\n[^-[]*\n.*//; /./!x;t
s/[${s}]*$//; s/\n[${b}]\{2,\}/${n} /;G;h
};
#test
/^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
s//\1\2.\3/
:print
/^[${s}]*\n\./{ s///;s/\n\./${n}/
/${bs}/{s/\n/ & /g;
s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
s/.${bs}//g;s/ \n /${n}/g
s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
};p;g;N;/\n$/!D
s//./; t print
};
#match
s/\n.*/ /; s/.${bs}//g
s/^\(${match}\).*/${n}\1/
/../{ s/^\([${s}]*\)\(.*\)/\1${n}/
x; s//${n}\1${n}. \2/; P
};D
");}
Коротко, робочий процес такий:
- будь-який рядок, який не є порожнім і не містить
\n
символу ewline, видаляється з виводу.
\n
Символи ewline ніколи не зустрічаються у просторі вхідного шаблону. Вони можуть мати місце лише в результаті редагування.
:print
і :indent
обидві взаємно залежні замкнуті петлі, і є єдиним способом отримання \n
лінії виходу.
:print
Цикл циклу починається, якщо провідними символами на рядку є ряд пробілів, за якими \n
йде символ ewline.
:indent
цикл починається з порожніх рядків - або на :print
циклічних рядках, які виходять з ладу #test
- але :indent
видаляє всі провідні \n
послідовності порожніх + евлайн зі свого результату.
- Після того, як
:print
він розпочнеться, він буде продовжувати тягнути вхідні лінії, знімати провідні пробіли до суми, знайденої на першому рядку в його циклі, переводити перескоку та підкреслювати втечу, що повертається в задній простір, на кольорові термінали та друкує результати, поки #test
не виходить з ладу.
- перед тим, як
:indent
почати, спочатку перевіряє h
старий пробіл на предмет можливого продовження відступу (наприклад, підрозділ) , а потім продовжує виводити дані доти, доки #test
не вдасться, і будь-який рядок, що слідує за першим, продовжує збігатися [-
. Коли рядок після першого не відповідає цьому шаблону, він видаляється - і згодом всі наступні рядки до наступного порожнього рядка.
#match
і #test
з'єднайте дві закриті петлі.
#test
проходить, коли провідна серія заготовок коротша за послідовність, за якою слідує остання \n
лінія виходу в послідовності рядків.
#match
випереджає провідні \n
лінії ewlines, необхідні для початку :print
циклу до будь-якої з :indent
вихідних послідовностей, які ведуть із збігом будь-якого аргументу командного рядка. Ті послідовності, які не робляться порожніми, - і порожній рядок, що виходить, передається назад :indent
.