在下面的示例中,作为$
我的 bash 提示符并⏎
象征着我按下 Enter 键,我如何构造一个命令/别名,foo
以便
$ foo bar⏎
是否会在命令行中输入/输入/预填充/键入“bar”(或我传递给命令的任何其他字符串),以便我可以在按 Enter 之前修改“bar”?例如
$ bar
…
$ barbaz⏎
我尝试过但没有成功echo bar > /dev/pts/123
,并且不想这样做xdotool
。这可能吗?
编辑:示例用例,“greppy 自动完成”:
我经常需要包含许多难以记住的参数的长命令。我将示例保存在文件中:
命令.txt:
ffmpeg -i infile.mp4 -c:v copy -c:a copy -y transcoded.mp4
sox in.wav out.wav remix 1 0
现在,如果我有上面指定的命令,我们称它为inject
,我可以有一个别名
grepcomplete () {
inject $(grep $0 commands.txt)
}
所以当我记得我需要混音一些东西,但我不记得了袜队及其参数,我可以输入grepcomplete remix
,然后坐在sox in.wav out.wav remix 1 0
我的命令行上,就像我输入它一样,准备好进行编辑和调整,然后按 Enter 执行它。无需选择、复制、粘贴任何内容。
正如卡米尔在评论中建议的那样,我可以使用 bash 的历史搜索(Ctrl-R),并通过history -r commands.txt
在我的 bashrc 中执行类似的操作来提供我自己的“历史”。
尽管如此,我的方法的好处是我可以轻松破解它,例如通过语法突出显示显示所有匹配项。
请注意,我自己已经回答了这个问题,并提供了该命令的实现inject
。
答案1
这是一个小而丑陋的解决方案,受到启发通过 perl 解决方案在每个提示后插入一个字符串,使用 TIOCSTI适配Python:
bash 函数,例如.bashrc
inject () {
(python -c "import fcntl; import termios; import sys
with open('/dev/stdout', 'w') as fd:
for c in ' '.join(sys.argv[1:]): fcntl.ioctl(fd, termios.TIOCSTI, c)" "$@" &)
}
用法:
inject foo bar
笔记:
- 目前无法处理 Unicode!我怀疑
for char in str
是罪魁祸首? - 子shell中的背景结构
( foo &)
防止在提示之前双重回显字符串 - 它会吃掉参数之间的空格:
inject foo bar
=inject foo bar
。使用inject "foo bar"
。 - 看起来这取决于时间,所以可能会出现竞争条件?
- 我有其他带有 Python 线程/多重处理的版本,可以在没有 bash 子 shell 的情况下完成,并且可能更适合管道、xargs 等。对于我的用例来说,这是最干净、最简单的解决方案。
答案2
您可以使用配置它~/.inputrc
。如果该文件不存在,则创建该文件,并添加以下内容:
Control-P: "foo "
现在,打开一个新终端并按Ctrl+ P,字符串foo
将在光标所在的位置输入。您可以选择适合您的快捷方式,并且它应该有效。
答案3
xdotool
仅适用于 X 环境,不适用于 TTY shell,也可能不适用于 Wayland。
我感觉你在问的是创建您自己的 bash 完成脚本。然后,用 key“注入”(调用完成)Tab
。
基本思想是这个complete
命令,它表示当用户按下Tab
按键时 bash 会建议什么:
$ complete -W "now tomorrow never" dothis
然后,输入
$ dothis to<Tab>
填充它:
$ dothis tomorrow
对于你的例子,
$ complete -W bar foo
$ foo<Space><Tab>
将产生
$ foo bar
您可以进一步编辑。
该complete
命令本身可以放入~/.bashrc
交互式 shell 创建期间运行。
答案4
在 Fish 中,相当于使用该commandline
函数。例如:
commandline 'echo next command'