Bash:使用自定义键盘快捷方式调用脚本?

比方说,我有一个脚本,“ myscript.sh ”,内容只是echo $PWD 。 我想以某种方式将此脚本绑定到bashgnome-terminal )中的组合键 – 以便当我按下该组合键时,将“ myscript.sh ”的输出插入(“粘贴”)终点站。

显然, bash历史和行操作是由readline处理的 – 而且我得到的bash键盘快捷键的参考文献可以参考readline

  • bash键盘快捷键
  • Bash参考手册:可绑定的Readline命令

我也在Bash参考手册:Readline Init File Syntax中看到bash的键绑定可以通过使用bind -p请参阅help bind [not'man bind'] )来列出。 所以也许这个问题最好被命名为“绑定macros到自定义键盘快捷键在readline ”:)但是在任何情况下,我想要做什么?

我想另一种方法是让脚本像“ pwd | xsel -b ”,然后在terminal上调用它,然后我可以粘贴; 但我仍然喜欢一个单一的键盘快捷键,而不是像Ctrl-Alt-H(这似乎没有用于任何东西),它会立即插入/粘贴脚本输出时按下。

提前致谢,
干杯!

编辑:只是为了澄清 – 这里是我的用例,我想这个设施。 我通常在项目文件myproject-folder-0012a ,通常命名为myproject-folder-0012a ,它由svn修改控制。 还有一堆这些文件夹。 因此,我常常在提交消息的第一个单词的地方是目录名,如下所示:

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

但那是我不喜欢的 – 首先我input11个字符,

 svn ci -m " 

然后,我不能使用自动完成获取名称(我在文件夹内) – 这意味着我要么完全键入它( 无法:) ),或者我复制粘贴从提示符(这需要select – 按鼠标,拖动,释放鼠标;然后按Ctrl + Shift + C,然后按Ctrl + Shift + V,如果我错过了所有的alignment,加上任何左/右键删除等,如果我使复制错误。

意义 – 这么多的工作,只是为了得到一个血腥的提交信息的血腥的文件夹名称:(我宁愿按类似(说)Ctrl-Alt-H,并有文件夹名称自动插入光标位置,用它完成:)

我对xselbuild议只是因为我可以把它放到一个“全局”脚本中 – 比如说把它作为/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" 

…哪种工作量减less了,但仍然 – 然后我必须记住脚本名称是什么,并且键入svn命令之前调用它(并且我并不总是记住)…而且仍然 – 我必须调用一个命令,然后按组合键; 为什么我不应该只按一个键组合一次,并做到这一点??! 🙂

那么,希望这个澄清我的问题好一点….

编辑2:但是,为什么bash键盘快捷键将是有用的另一个原因是,那么我也可以“粘贴/插入当前目录名称”不仅在shell命令 – 而且在terminal程序,如nano可能会说, ,比较难直接使用bash脚本或function扩展 )。

Solutions Collecting From Web of "Bash:使用自定义键盘快捷方式调用脚本?"

简单版本:

这个命令在shell提示符下:

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

或者将这行添加到你的~/.inputrc

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

将导致Alte在命令行中插入当前目录的基本名称。 它要求存在\e\Ce的readline函数shell-expand-line的默认绑定(如果不同,可以对其进行修改)。 我也假设你正在使用Bash的emacs模式。

不幸的是,它导致已经键入的东西也被扩展。 其中一个影响是键入后:

 svn ci -m " 

并按Alte ,引号将消失。 有几种方法可以解决这个问题。

一,假设你将失去的是报价,并手动将其添加回来,或让readline宏为你添加:

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

这只是不是很满意。

高级版本:

或者,二,杀死线路,做插入,然后把线路拉回来:

 bind '"\ee": " \Cu \Ca\Ck${PWD##*/}\e\Ce\Cy\Ca\Cy\ey\b"' 

要么

 bind '"\ee": " \Cu \Ca\Ck${PWD##*/}\e\Ce\Cy\Ca\Cy\ey\b\ef\Cf"' 

这使得剩下的行完好无损(没有其他的东西被扩展或者删除),但是它使用了kill戒指,所以它可能会把它保留在与你期望的不同的状态(如果你正在使用的话)。 它还在插入的目录名称后面插入一个空格(宏中的空格用于确保如果宏在该行的开始或结尾处执行,则旧的kill-ring内容不会反刍)。 无论光标在行中的位置,宏应该工作。 插入将在光标的位置进行,使光标保持在相同的位置[在第一个版本中]。

编辑:第二个版本将光标放在插入的dirname和空格之后。

编辑2:

readline函数shell-forward-word (unbound)比forward-word\ef )做得更好。 你可以使用这样的:

 bind '"\ew":shell-forward-word' bind '"\ee": " \Cu \Ca\Ck${PWD##*/}\e\Ce\Cy\Ca\Cy\ey\b\ew\Cf"' 

顺便说一下,您应该知道Bash键盘快捷键在其他程序(如nano中不活动。

好吧,不是一个真正的答案,但我只想总结一下我所得到的评论,这对我的问题是有用的。 然而,这个问题 – 关于运行任意脚本的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注意:确保在将这些行添加到.bashrc后重新加载bash ,例如,只需在当前终端中键入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 

基本上,我最初误解了Reese Moore的建议 – 确实可以使用反引号 – 考虑这个命令会话( 在上面的命令已经运行之后 ):

 $ 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\ 

感谢迄今为止的评论,
干杯!

使用单键按下你想做的一种方法是利用bash中的可编程完成。 你可能用bash_completion工具/包设置了一些可编程的完成。 如果没有,请仔细查看具体情况。

这个想法是,当你在svn提交消息的开始点击时,可编程完成就会识别出来,然后让它返回一个你想要插入的文本(当前目录的基本名称)的单个完成。

我只涉及到可编程完成,所以我不能给你详细的信息,但是上面提到的bash_completion包或者subversion完成脚本可能是一个好的开始。