Search code examples
bashshellunixshposix

How would you pipe options in a shell select loop?


My goal is to pipe options from one command to a function that generates a menu using select.

Shell select loop reads from stdin, which by default is linked to keyboard inputs, when you are in a pipe however, stdin becomes the stdout of the previous command (I may be oversimplifying here).

The bash help says that select completes when EOF is read, which is unfortunate, because if you read all options from the pipe, then select will not be able to open it, and return immediately.

This is what I would like to do, it does not work:

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

echo "ga bu zo me" | pipe_select

Solution

  • A more general approach, which allows spaces in select items

    #!/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