我正在尝试编写一个 bash 脚本将字符串通过管道传输到 rofi 中。这些字符串是由函数连续生成的gen_x
。
该函数gen_x
有时(仅当满足条件时)输出新字符串。我目前gen_x
在无限循环中使用 if 语句实现 - 函数。我想将此功能通过管道传输到 rofi 中。当在 rofi 中选择一个项目时,rofi 应输出所选项目,gen_x
并且 rofi 应结束。
当使用每个循环输出一个新元素的无限循环时(如 中所示gen_b
),该脚本完全按照我上面描述的方式执行。但是,当我在函数中实现 if 语句并且仅在条件为真时打印新元素时,程序永远不会结束。我不确定这是否是由于gen_x
rofi 造成的。
简化代码
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"
}