假设我有一个脚本“myscript.sh
”,内容只是echo $PWD
。我想以某种方式将此脚本绑定到bash
(gnome-terminal
)中的关键组合 - 这样当我按下此组合键时,会插入“myscript.sh
”的输出(“粘贴“)在终端的光标位置。
显然bash
历史记录和行操作由readline处理 - 以及bash
键盘快捷键的参考,请参考readline
:
我还在Bash Reference Manual: Readline Init File Syntax中看到bash
的键绑定可以使用bind -p
列出(请参阅help bind
[不是'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
符号链接(,显然,脚本的内容是{{1}而不仅仅是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"
命令(而且我并不总是记得那个... ...而且 - 我必须拨打一个命令,然后按一个键组合;为什么我不应该只按一次键组合,并完成它? :)
嗯,希望这能更好地澄清我的问题......
编辑2:然而,svn
键盘快捷键有用的另一个原因是,我还可以“粘贴/插入当前目录名称”不仅在shell命令中 - 而且还在终端程序中,比如{{1 (可能会更难以直接使用bash
脚本或函数扩展)。
答案 0 :(得分:10)
shell命令提示符下的命令:
bind '"\ee": "${PWD##*/}\e\C-e"'
或此行已添加到您的~/.inputrc
:
"\ee": "${PWD##*/}\e\C-e"
将导致 Alt - e 在命令行中插入当前目录的基名。它要求存在shell-expand-line
的读取函数\e\C-e
的默认绑定(如果它不同,则可以调整它)。我也假设你正在使用Bash的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"'
这使得该行的其余部分保持原样(没有其他内容被扩展或删除),但它使用了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"'
顺便说一下,您应该知道Bash键盘快捷键在nano
等其他程序中无效。
答案 1 :(得分:0)
好的,不是一个真正的答案,但我只是想总结一下我到目前为止的评论,这对我的问题很有用。但是,现在的问题 - 关于运行任意脚本的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
基本上,我最初误解了Reese Moore的建议 - 你确实可以使用反引号 - 考虑这个命令会话(在上面的命令运行之后):
$ bpwd
Desktop\
$ bpwd2
Desktop\
$ echo `bpwd`
Desktop
$ echo "`bpwd2` 2"
Desktop 2
这就是我需要了解的Moore的“来自反向命令的输出将用作执行命令的输入”(但是,还需要注意清理行结尾)输出);或者,就我而言,我可以致电
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\
感谢到目前为止的评论,
干杯!
答案 2 :(得分:0)
通过单键按键完成所需操作的一种方法是利用bash中的可编程完成功能。您可以使用bash_completion工具/包进行一些可编程的完成设置。如果没有,请查看它以了解它是如何完成的具体细节。
我们的想法是,当你在svn提交消息的开头命中时,可以识别可编程完成,然后让它返回一个完成,这是你要插入的文本(当前目录的基本名称)。 / p>
我只涉及可编程完成,因此我无法向您提供详细信息,但上述bash_completion包或subversion completion script可能是一个良好的开端。