【问题标题】:How would you pipe options in a shell select loop? [duplicate]您将如何在 shell 选择循环中使用管道选项? [复制]
【发布时间】:2020-05-29 16:34:53
【问题描述】:

我的目标是将选项从一个命令传递到使用select 生成菜单的函数。

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

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

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

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

echo "ga bu zo me" | pipe_select

【问题讨论】:

    标签: bash shell unix sh posix


    【解决方案1】:

    一种更通用的方法,允许在选定项目中使用空格

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

    【讨论】:

    • 谢谢,我没想过以这种方式使用readarray / mapfile。在我的实际案例中,我通过 curl 获得 JSON 有效负载,然后使用 jq 在我的 select 函数中解析它。
    • readarray 比 cat/exec 简单。
    【解决方案2】:

    我找到的解决方法如下:

    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
    

    我有一个命令“生成”选项,我使用exec 将我的stdin 从管道的恶意损坏中“保存”。当pipe_select 被调用时,我解析前一个命令的输出,然后我“重置”stdin 以供select 读取。之后的一切都是标准的select 行为。

    【讨论】:

      【解决方案3】:

      From another answer

      pipe_select() {
              opts=$(cat <&0);
              select foo in ${opts}
              do
                      echo ${foo};
                      break;
              done < /dev/tty
      }
      
      echo "ga bu zo me" | pipe_select`
      

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

      【讨论】:

      • 你应该接受他的回答,或者至少点赞,而不是在这里复制。
      • 谢谢,我对另一个问题投了赞成票。 (已被接受)。
      猜你喜欢
      • 2016-02-19
      • 2011-01-04
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 2023-03-08
      • 2012-06-19
      • 2018-02-24
      • 2018-12-01
      相关资源
      最近更新 更多