Команда Fu

Thank you for reading this post, don't forget to subscribe!

Анатомия завершения программы

Ока­зы­ва­ет­ся, завер­ше­ние зави­сит от кон­крет­ной биб­лио­те­ки GNU, извест­ной как readline.  Он чита­ет текст для мно­же­ства раз­лич­ных про­грамм, вклю­чая Bash, и вы може­те настро­ить его, исполь­зуя  файл .inputrc в вашем домаш­нем ката­ло­ге. Напри­мер, вот при­мер.inputrc :

 

Это не выгля­дит мно­го, но есть систем­ная кон­фи­гу­ра­ция в /etc/inputrc, кото­рая намно­го более суще­ствен­на. Вы так­же може­те выпол­нить опре­де­лен­ные коман­ды, кото­рые будут изме­нять кон­фи­гу­ра­цию на лету. Напри­мер, встро­ен­ный в Bash «bind» может настро­ить все, а так­же пока­жет вам длин­ный спи­сок того, что уже настро­е­но. Если вы дела­е­те эту команду:

 

Вы уви­ди­те длин­ный спи­сок резуль­та­тов. Инте­рес­ны сле­ду­ю­щие несколь­ко строк:

 

Ваш может отли­чать­ся, но, по сути, это гово­рит о том, что, когда появ­ля­ет­ся кла­ви­ша табу­ля­ции или двой­ной выход, выпол­нить опе­ра­цию завер­ше­ния. Есть так­же несколь­ко спе­ци­а­ли­зи­ро­ван­ных допол­не­ний, кото­рые начи­на­ют­ся с побега.

 

Но как это работает?

Есть три встро­ен­ные коман­ды обо­лоч­ки, кото­рые вза­и­мо­дей­ству­ют, что­бы управ­лять завер­ше­ни­ем, это:

  • complete – настро­ить завершение
  • compgen – гене­ри­ру­ет воз­мож­ные дополнения
  • compopt  – Изме­нить пара­мет­ры завершения

 

Мы не будем вда­вать­ся во все воз­мож­ные вари­ан­ты, хотя вы може­те про­чи­тать руко­вод­ство по Bash, если вам инте­рес­но. Для наших целей вам пона­до­бит­ся все­го несколь­ко, и все три коман­ды в боль­шин­стве слу­ча­ев при­ни­ма­ют оди­на­ко­вые аргументы.

Давай­те попро­бу­ем несколь­ко вещей с compgen, так как это то, что bash в кон­це кон­цов вызы­ва­ет для завер­ше­ния. Пред­по­ло­жим, вы наби­ра­е­те коман­ду ls в команд­ной стро­ке и нажи­ма­е­те tab. Bash сде­ла­ет сле­ду­ю­щий вывод:

Вы уви­ди­те вывод (в зави­си­мо­сти от того, что вы уста­но­ви­ли) всех команд, начи­на­ю­щих­ся с ls , таких как ls , lsusb , lspci и т. д. Вы так­же може­те исполь­зо­вать более совре­мен­ный син­так­сис «-A command» для полу­че­ния того же результата.

Попро­буй­те это:

 

Опять же, вы може­те исполь­зо­вать ката­лог -A, если хоти­те. Понят­но, что это выво­дит ката­ло­ги. Это хоро­шо, но как Bash узна­ет, какие опции нуж­но пере­дать в compgen? Вот где при­хо­дит коман­да complete. Коман­да complete может ука­зать Bash вызвать функ­цию обо­лоч­ки или коман­ду в ответ на завер­ше­ние выпол­не­ния опре­де­лен­ной коман­ды. Он так­же может уста­но­вить один для пустой коман­ды или коман­ды, у кото­рой ина­че нет соот­вет­ству­ю­ще­го пра­ви­ла. Есть так­же хоро­шие ярлы­ки для общих случаев.

Рас­смот­рим скрипт под назва­ни­ем burnhex. Если вы вве­де­те Burnhex , про­бел и вклад­ку, Bash (через readline ) пред­ло­жит вам все фай­лы в теку­щем ката­ло­ге для завер­ше­ния. Одна­ко вы може­те дога­дать­ся, что вам нуж­ны толь­ко фай­лы, закан­чи­ва­ю­щи­е­ся на .hex. Вы може­те лег­ко сде­лать с помо­щью complete:

 

Теперь будут отоб­ра­жать­ся толь­ко фай­лы с рас­ши­ре­ни­ем .hex.

Что­бы взгля­нуть на еще более слож­ные допол­не­ния, давай­те нач­нем с про­стой функ­ции обо­лоч­ки. По согла­ше­нию, они начи­на­ют­ся с под­чер­ки­ва­ния, хотя это не тех­ни­че­ское требование:

 

Это гово­рит систе­ме, что у нас есть два допол­не­ния. Давай­те пред­ста­вим, что у нас есть скрипт или про­грам­ма под назва­ни­ем « goandreyex », и мы хотим, что­бы это было завер­ше­ни­ем (коман­да не долж­на суще­ство­вать, что­бы это работало):

 

Теперь, если вы введете:

 

Вы уви­ди­те свое завер­ше­ние в дей­ствии. Систе­ма доста­точ­но умна, что­бы знать, что она может запол­нить часть «andreyex», посколь­ку оба вари­ан­та начи­на­ют­ся с это­го. Если вы набе­ре­те «c» или «i» и сно­ва нажме­те «Tab», он выбе­рет пра­виль­ный вариант.

Кста­ти, функ­ция полу­ча­ет три аргу­мен­та, кото­рые мы не исполь­зу­ем. Пер­вый аргу­мент ($ 1) – это имя актив­ной коман­ды, вто­рой – завер­ша­е­мое сло­во, а тре­тий – сло­во перед теку­щим сло­вом. Напри­мер, рас­смот­рим стро­ку ниже и три аргу­мен­та следующие:

 

Так­же есть несколь­ко пере­мен­ных сре­ды, кото­рые вы хоти­те уста­но­вить, если хоти­те извлечь всю стро­ку или опре­де­лить, как поль­зо­ва­тель вызвал завер­ше­ние. Для про­стых слу­ча­ев вам, веро­ят­но, это не нужно.

Конеч­но, это про­стой при­мер. Для вещей, кото­рые боль­ше, чем вы може­те обра­бо­тать в функ­ции, вы так­же може­те запу­стить пол­но­цен­ную коман­ду, исполь­зуя -C вме­сто -F. Коман­ды полу­ча­ют оди­на­ко­вые аргу­мен­ты и боль­шин­ство оди­на­ко­вых пере­мен­ных среды.

Кро­ме того, помни­те опции -c и -d для compgen ? Они тоже рабо­та­ют здесь. Так что если у вас есть коман­да с име­нем foobar, для кото­рой в каче­стве аргу­мен­та нуж­но ука­зать имя ката­ло­га, вы може­те сказать:

 

Вы даже може­те вызвать compgen в сво­ей функ­ции или коман­де, что­бы гене­ри­ро­вать дан­ные напря­мую или для даль­ней­шей филь­тра­ции и допол­не­ния в вашем коде. Это может быть доволь­но слож­но, и если вы посмот­ри­те на неко­то­рые из встро­ен­ных, вы пой­ме­те, что мы име­ем в виду.

В целом, мно­гие сце­на­рии завер­ше­ния нахо­дят­ся либо в /etc/bash_completion.d или /usr/share/bash-completions. Да, один из них – под­чер­ки­ва­ние, а дру­гой – тире. Одна из радо­стей Linux заклю­ча­ет­ся в том, что каж­дая систе­ма немно­го отличается.

 

Более типичный пример

Рас­смот­рим коман­ду ftp. Вы може­те узнать, что это за завер­ше­ние, набрав:

 

Резуль­тат будет выгля­деть так:

 

Это озна­ча­ет, что есть функ­ция обо­лоч­ки с име­нем _known_hosts. Если вы хоти­те уви­деть, как это выгля­дит, попробуйте:

 

Вы долж­ны уви­деть что-то вро­де этого:

 

Оче­вид­но, что насто­я­щая рабо­та выпол­ня­ет­ся в _known_hosts_real, и вы може­те сбро­сить ее таким же обра­зом. Это слож­но, но вы може­те дога­дать­ся, что он будет сбра­сы­вать име­на хостов, о кото­рых зна­ет ком­пью­тер. Есть и дру­гие вспо­мо­га­тель­ные функ­ции, такие как _init_completion . Дело не в том, как они рабо­та­ют, а в том, что они суще­ству­ют, и вы може­те исполь­зо­вать их так же, как это дела­ет уста­нов­ка завер­ше­ния ftp.