sda*_*aau 4 linux bash customization keyboard-shortcuts readline
假设我有一个脚本," myscript.sh
"内容很简单echo $PWD
.我想以某种方式将这个脚本绑定到bash
(gnome-terminal
)中的一个键组合- 这样当我按下这个组合键时," myscript.sh
" 的输出被插入("粘贴")在终端的光标位置.
显然,bash
历史和行操作由readline处理- 我获得的bash
键盘快捷键参考,请参考readline
:
我还在Bash参考手册中看到:Readline初始化文件语法,bash
可以通过使用列出键绑定bind -p
(请参阅help bind
[not'man bind']了解更多信息).所以也许这个问题最好被标题为"_binding宏到自定义键盘快捷键readline
":)但无论如何,我想要做什么?
我想一个替代方案是让脚本像" pwd | xsel -b
",然后我在终端上调用它 - 然后我可以粘贴; 但我仍然喜欢一个键盘快捷键,比如Ctrl-Alt-H(似乎没有用于任何东西),它会在按下时立即插入/粘贴脚本输出.
提前谢谢,
干杯!
编辑:只是为了澄清 - 这是我的用例,我喜欢这个设施.我通常都cd
在一个项目文件夹中,通常命名为类似的myproject-folder-0012a
,受到版本控制svn
.还有一堆这些文件夹.所以我经常提交消息的第一个字是目录名,如下所示:
svn ci -m "myproject-folder-0012a: here a commit message"
Run Code Online (Sandbox Code Playgroud)
但这就是我不喜欢的 - 首先我输入11个字符,这些字符速度相当快:
svn ci -m "
Run Code Online (Sandbox Code Playgroud)
然后,我不能使用自动完成来获取名称(我在文件夹中) - 这意味着我要么必须完全键入它(没办法:)),或者我从提示中复制粘贴(这需要选择 - 按鼠标,拖动,释放鼠标;然后按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"
Run Code Online (Sandbox Code Playgroud)
...哪种工作量减少了,但仍然 - 然后我必须记住脚本名称是什么,并在我输入svn
命令之前调用它(我并不总是记得那个)......并且仍然 -我必须调用一个命令,然后按一个键组合; 为什么我不应该只按一次键组合,并完成它?:)
好吧,希望这能更好地澄清我的问题....
编辑2:然而,bash
键盘快捷键有用的另一个原因是,我还可以"粘贴/插入当前目录名称"不仅在shell命令中 - 而且还在终端程序中,比如说nano
(可以说,它可能是更难以直接使用bash
脚本或函数扩展).
Pau*_*ce. 10
shell命令提示符下的此命令:
bind '"\ee": "${PWD##*/}\e\C-e"'
Run Code Online (Sandbox Code Playgroud)
或者这一行添加到您的~/.inputrc
:
"\ee": "${PWD##*/}\e\C-e"
Run Code Online (Sandbox Code Playgroud)
将导致Alt- e在命令行上插入当前目录的基名.它要求默认readline的功能的结合shell-expand-line
是\e\C-e
存在的(这可能是,如果它是不同的改编).我也假设你正在使用Bash的emacs模式.
不幸的是,它导致已经输入的内容也被扩展.其中一个影响是输入后:
svn ci -m "
Run Code Online (Sandbox Code Playgroud)
并按Alt- e,引号将消失.有几种方法可以解决这个问题.
一,假设您将失去的只是引用,并手动将其添加回来或让readline宏为您添加:
bind '"\ee": "${PWD##*/}\e\C-e\eb\"\C-e"'
Run Code Online (Sandbox Code Playgroud)
这不是很令人满意.
或者,两个,杀死线,插入,然后拉回线:
bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b"'
Run Code Online (Sandbox Code Playgroud)
要么
bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b\ef\C-f"'
Run Code Online (Sandbox Code Playgroud)
这使得线的其余部分保持完整(没有其他内容被扩展或删除),但是它使用了kill ring,因此它可能会使其处于与您预期不同的状态(如果您正在使用它).它还在插入的目录名称后面插入一个空格(宏中的空格用于确保如果在行的开头或结尾执行宏,则不会反转旧的kill-ring内容).无论光标在行中的位置如何,宏都应该工作.插入将在光标位置进行,将光标留在[第一个版本]中的相同位置.
编辑:第二个版本将光标留在插入的目录名和空格之后.
编辑2:
readline函数shell-forward-word
(未绑定)比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"'
Run Code Online (Sandbox Code Playgroud)
顺便说一句,您应该知道Bash键盘快捷键在其他程序中不活动nano
.