Bash: вызвать скрипт с настроенными сочетаниями клавиш? - PullRequest
4 голосов
/ 08 ноября 2010

Допустим, у меня есть скрипт "myscript.sh", содержимое которого просто echo $PWD. Я хотел бы как-то привязать этот скрипт к комбинации клавиш в bash (gnome-terminal) - чтобы при нажатии этой комбинации клавиш вывод «myscript.sh» вставлялся («вставлялся») в курсор положение в терминале.

Очевидно, bash история и манипуляции со строками обрабатываются readline - и ссылками, которые я получил для bash сочетаний клавиш, сделайте ссылку readline:

Я также видел в Справочном руководстве Bash: Readline Синтаксис файла инициализации , что привязки клавиш для bash могут быть перечислены с помощью bind -p ( см. help bind [not ' man bind '] для более ). Поэтому, возможно, этот вопрос лучше назвать «привязка макросов к пользовательским сочетаниям клавиш в readline» :) Но в любом случае, что я хочу сделать?

Полагаю, альтернативой было бы, чтобы скрипт был чем-то вроде "pwd | xsel -b", а затем я вызываю его на терминале - и я могу вставить его позже; но вместо этого я бы хотел использовать одну комбинацию клавиш, например, Ctrl-Alt-H (которая, кажется, ни для чего не используется), которая будет сразу вставлять / вставлять вывод скрипта при нажатии.

Заранее спасибо,
Ура!


РЕДАКТИРОВАТЬ: Просто чтобы уточнить - вот мой случай использования, где я хотел бы это средство. Я обычно cd нахожусь в папке проекта, обычно называемой чем-то вроде myproject-folder-0012a, которая находится под контролем ревизии svn. И есть куча этих папок. Поэтому довольно часто я делаю коммиты, где первое слово сообщения - это имя каталога, например:

svn ci -m "myproject-folder-0012a: here a commit message"

Но это то, что мне не нравится - сначала я набираю 11 символов, которые идут довольно быстро:

svn ci -m "

И затем, я не могу использовать автозаполнение, чтобы получить имя (я нахожусь в папке) - это означает, что я должен либо ввести его полностью ( никак:) ), либо скопировать и вставить его из приглашения (которое требует выбора - нажмите мышь, перетащите, отпустите кнопку мыши; затем Ctrl + Shift + C, а затем Ctrl + Shift + V, а также любые клавиши влево / вправо, если я пропущу выравнивание, плюс удаления и тому подобное, если я сделаю копировать неправильно).

Значение - так много работы, просто чтобы получить кровавое имя папки для сообщения кровавого коммита :( Я бы НАМНОГО предпочел нажать что-то вроде (скажем) Ctrl-Alt-H, и имя папки автоматически вставилось бы в позиции курсора и покончим с этим :)

Мое предложение для xsel только потому, что я мог бы поместить его в «глобальный» скрипт - скажем, символическую ссылку как /usr/bin/myscript ( и, очевидно, содержимое скрипта echo $(basename $PWD), а не просто pwd для моих нужд ), и тогда я смогу сделать:

$ myscript       # this puts directory name in clipboard
$ svn ci -m "[CTRL+SHIFT+V TO PASTE HERE]myproject-folder-0012a[NOW TYPE]: here a commit message"

... что делает рабочую нагрузку меньше, но все же - тогда я должен вспомнить, как называется сценарий, и назвать его, до Я набираю команду svn (и я не не всегда это помню) ... И все же - мне нужно вызвать команду, а затем нажать комбинацию клавиш; почему я не должен просто нажать комбинацию клавиш один раз и покончить с этим ??! :)

Хорошо, надеюсь, это прояснит мою проблему немного лучше ...


РЕДАКТИРОВАТЬ 2: Однако, еще одна причина, по которой было бы полезно сочетание клавиш bash, заключается в том, что тогда я мог бы также «вставлять / вставлять текущее имя каталога» не только в командах оболочки, но и в терминальных программах, например, как nano ( где, возможно, будет сложнее использовать bash сценарий или расширение функции напрямую ).

Ответы [ 3 ]

10 голосов
/ 08 ноября 2010

Простая версия:

Эта команда в приглашении оболочки:

bind '"\ee": "${PWD##*/}\e\C-e"'

или эта строка добавлена ​​к вашему ~/.inputrc:

"\ee": "${PWD##*/}\e\C-e"

заставит Alt - e вставить базовое имя текущего каталога в командной строке. Требуется наличие привязки по умолчанию для функции readline shell-expand-line, которая \e\C-e (это можно изменить, если она отличается). Я также предполагаю, что вы используете режим emacs Баша.

К сожалению, это также приводит к расширению уже набранных вещей Одним из последствий этого является то, что после ввода:

svn ci -m "

и нажатие Alt - e , кавычка исчезнет. Есть несколько способов справиться с этим.

Во-первых, предположим, что все, что вы потеряете, это кавычка и либо добавьте ее вручную, либо добавьте макрос readline для вас:

bind '"\ee": "${PWD##*/}\e\C-e\eb\"\C-e"'

что не очень хорошо.

Расширенная версия:

Или, два, убейте строку, сделайте вставку, затем верните строку назад:

bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b"'

или

bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b\ef\C-f"'

Это оставляет остальную часть строки нетронутой (ничего больше не расширяется или удаляется), но при этом используется список уничтожений, поэтому он может оставить его в состоянии, отличном от ожидаемого (если вы его используете). Он также вставляет пробел после вставленного имени каталога (пробелы в макросе используются для гарантии того, что старое содержимое списка уничтожений не будет срыгнуто, если макрос выполняется в начале или в конце строки). Макрос должен работать независимо от положения курсора в строке. Вставка будет сделана в позиции курсора, оставляя курсор в той же позиции [в первой версии].

Редактировать: Вторая версия оставляет курсор после введенного имени и пробела.

Редактировать 2:

Функция readline shell-forward-word (unbound) справляется с этой задачей лучше, чем forward-word (\ef). Вы можете использовать это так:

bind '"\ew":shell-forward-word'
bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b\ew\C-f"'

Кстати, вы должны знать, что сочетания клавиш Bash не активны в других программах, таких как nano.

0 голосов
/ 08 ноября 2010

Один из способов сделать то, что вы хотите одним нажатием клавиши, - воспользоваться программируемым завершением в bash.Возможно, вы настроили какое-то программируемое завершение с помощью инструмента / пакета bash_completion.Если нет, посмотрите на это, чтобы увидеть особенности того, как это делается.

Идея состоит в том, чтобы программируемое завершение распознавало, когда вы нажали в начале сообщения фиксации SVN, а затем вернуло однозавершение - это текст, который вы хотите вставить (базовое имя текущего каталога).

Я только баловался с программируемым завершением, поэтому я не могу дать вам подробности, но вышеупомянутый пакет bash_completion или скрипт завершения subversion может быть хорошим началом.

0 голосов
/ 08 ноября 2010

Хорошо, на самом деле это не ответ, но я просто хотел бы обобщить полученные мной комментарии, которые полезны для моей проблемы. Тем не менее, вопрос в том виде, в котором он существует - в отношении сочетаний клавиш bash, запускающих произвольные сценарии, - до сих пор остается без ответа ( Я все же предпочел бы делать все это с помощью одной клавиши:) )


Во-первых, я могу использовать «глобальный» скрипт, например:

$ sudo bash -c 'cat > /usr/bin/bpwd <<EOF
#!/bin/bash
basepwd=\$(basename \$(pwd))
echo -n \$basepwd                 # suppress line ending
# exec 1>/dev/null               # debug: redir stdout to null
echo -n \$basepwd | xsel -i -b    # suppress LF, and make xsel read from stdin 
# exec 1>/dev/tty                # debug: restore stdout
EOF
chmod +x /usr/bin/bpwd'

Или я могу добавить bash функций к моему примечанию .bashrc (: обязательно перезагрузите bash после добавления этих строк в .bashrc - например, просто набрав bash в ваш текущий терминал ):

$ echo '
bpwd2() { basepwd=${PWD##*/} ; echo -n $basepwd | xsel -i -b ; echo -n $basepwd ; }
svnci-test() { echo -n "$(bpwd2): $*" ; }
svnci-m() { svn ci -m "$(bpwd2): $*" ; }' >> ~/.bashrc


По сути, я изначально неправильно понял предложение Риз Мур - вы действительно можете использовать обратные пометки - рассмотрите эту сессию команд ( после того, как вышеупомянутые команды были выполнены ):

$ bpwd
Desktop\
$ bpwd2
Desktop\
$ echo `bpwd`
Desktop
$ echo "`bpwd2` 2"
Desktop 2

Это то, что мне нужно, чтобы понять, что « вывод Мура будет использоваться в качестве ввода для выполненной команды » Мура (однако также необходимо позаботиться о том, чтобы очистить окончания строк от выход); или, в моем случае, я могу позвонить

svn ci -m "`bpwd`: my message here"
# svn ci -m "${PWD##*/}: my message here" # alternatively

... или я мог бы последовать совету camh и использовать svnci-m в качестве функции ( в моем случае, я почти никогда не использую дополнительные аргументы для svn ci, и поэтому моя версия немного отличается ). И чтобы проверить правильность передачи аргументов, я могу использовать функцию svnci-test:

$ svnci-test "my message"
Desktop: my message\


Спасибо за комментарии,
Ура!

...