您将如何在 shell select 循环中传递选项?

How would you pipe options in a shell select loop?

我的目标是使用 select.

将选项从一个命令传送到一个生成菜单的函数

Shell select 循环从 stdin 读取,default is linked to keyboard inputs,但是当你在管道中时,stdin 变成 stdout 之前的命令(我在这里可能过于简单化了)。

bash help says that select completes when EOF is read,这是不幸的,因为如果你从管道中读取所有选项,那么select将无法打开它,并且return立即。

这就是我想要做的,它不起作用:

pipe_select() {
        select foo in $(cat <&0)
        do
                echo ${foo};
                break;
        done
}

echo "ga bu zo me" | pipe_select

我找到的解决方案如下:

pipe_select() {
        opts=$(cat <&0);
        exec <&3 3<&-;
        select foo in ${opts}
        do
                echo ${foo};
                break;
        done
}

exec 3<&0
echo "ga bu zo me" | pipe_select

我有一个命令 "generating" 选项,我使用 exec 到 "save" 我的 stdin 来自管道的邪恶腐败。当 pipe_select 被调用时,我解析前一个命令的输出,然后我 "reset" 将 stdin 用于 select 读取。其他一切都只是之后的标准 select 行为。

pipe_select() {
        opts=$(cat <&0);
        select foo in ${opts}
        do
                echo ${foo};
                break;
        done < /dev/tty
}

echo "ga bu zo me" | pipe_select`

这其实是我一直想做的事情! :p

一种更通用的方法,允许 select 项中的空格

#!/usr/bin/env bash

pipe_select() {
    readarray -t opts
    select foo in "${opts[@]}"
    do  
        echo ${foo};
        break;
    done < /dev/tty
}

printf "%s\n" ga bu zo me | pipe_select
printf "%s\n" "option 1" "option 2" | pipe_select