我想在 fzf 中选择某些内容,并将该选择键入我可以编辑并最终调用的命令。解决方案可能如下所示:
seq 5 | sed "s/^/echo Testing /" | fzf | xargs -I{} xdotool type "{}"
但终端上的输出如下所示:
[me@~~~_09:40:22 ~]$ seq 5 | sed "s/^/echo Testing /" | fzf | xargs -I{} xdotool type "{}"
echo Testing 3[me@~~~_09:40:26 ~]$ echo Testing 3
它可以工作,但可能会打印两次长命令。这更像是 xdotool 的“问题”。它在调用命令完成之前输入文本,这就是为什么它先被写入,然后命令完成,并且写入的内容在提示符中“重复”。
我想知道是否有可能以某种方式启动此演示命令来获得:
[me@~~~_09:40:22 ~]$ seq 5 | sed "s/^/echo Testing /" | fzf | xargs -I{} xdotool type "{}"
[me@~~~_09:40:26 ~]$ echo Testing 3
我尝试使用延迟、嵌套命令,但我搞不懂。有人能帮忙吗?
答案1
每当在终端中输入任何内容时,它都会被回显。这就是我们看到的。当 bash 重新启动时,它会将终端设置为原始模式,以便处理所有特殊字符和编辑等,因此也会关闭回显。然后它会读取xdotool
输入的内容,并忠实地回显它。
您可以通过在运行之前关闭 echo 来解决这个问题xdotool
,例如:
.. fzf | (stty -F /dev/tty -echo; xargs -I{} xdotool type "{}"; stty -F /dev/tty echo)
注意,除了xdotool
,您还可以使用 ioctl TIOCSTI
。有多个 C 源代码和 perl 脚本可以执行此操作。下面是包含的一个stty
:
#!/usr/bin/perl
# https://superuser.com/a/1663171/458747
use strict;
eval 'sub TIOCSTI () {0x5412;}' unless defined(&TIOCSTI);
system('stty -F /dev/tty -echo');
my $str;
if($#ARGV<0){ $str = join("",<STDIN>); } # read stdin if no args
else{ $str = join(" ",@ARGV); }
foreach my $ch (split('',$str)){
ioctl(STDOUT, &TIOCSTI, $ch) or die $!;
}
system('stty -F /dev/tty echo');
如果将其放入文件中,pushtype
则可以避免xargs
使用...fzf|pushtype
。
答案2
为什么不直接这样做:
(seq 5|fzf|xargs -I{} xdotool type "{}") > /dev/null
或者反过来:
(sleep 1; echo "hello"|xargs -I{} xdotool type "{}")& > /dev/null; fzf
或者更好的历史搜索:
eval "$(fzf --bash)"
因此你可以使用以下方式搜索Ctrl+R
或者通过选择来启动某件事?
fzf --bind "enter:become(vi {})"