将连续输出输送到 rofi

将连续输出输送到 rofi

我正在尝试编写一个 bash 脚本将字符串通过管道传输到 rofi 中。这些字符串是由函数连续生成的gen_x

该函数gen_x有时(仅当满足条件时)输出新字符串。我目前gen_x在无限循环中使用 if 语句实现 - 函数。我想将此功能通过管道传输到 rofi 中。当在 rofi 中选择一个项目时,rofi 应输出所选项目,gen_x并且 rofi 应结束。

当使用每个循环输出一个新元素的无限循环时(如 中所示gen_b),该脚本完全按照我上面描述的方式执行。但是,当我在函数中实现 if 语句并且仅在条件为真时打印新元素时,程序永远不会结束。我不确定这是否是由于gen_xrofi 造成的。

简化代码

gen_a(){ while true; do if [[ "$v" == "" ]]; then echo "Test"; v=1; fi; sleep 1; done }
gen_b(){ while true; do                             echo "Test";            sleep 1; done }

gen_a | rofi -dmenu # -> this outputs Test and does not end
gen_b | rofi -dmenu # -> this outputs Test and ends properly

有没有办法在 while 循环中使用条件,并使程序正确结束。

答案1

rofi切换到异步模式在默认情况下读取 25 行输入之前。这可以通过以下方式更改:

-async-pre-read [number] 在切换到异步模式之前读取多个阻塞条目

选项。

所以:

cmd | rofi -async-pre-read 1 -dmenu

让它在读取一行后立即显示菜单cmd

当选择一个项目时,rofi将打印它并终止。 cmd此后,当它下次像往常一样向 stdout(现在是一个损坏的管道)写入内容时,将被 SIGPIPE 杀死。

要立即杀死它,常见的方法是:

sh -c 'echo "$$"; exec cmd' | {
  IFS= read -r pid
  rofi -async-pre-read 1 -dmenu
  kill -s PIPE "$pid"
}

相关内容