【问题标题】:How to pipe data to interactive bash script and pipe output to another command?如何将数据传输到交互式 bash 脚本并将输出传输到另一个命令?
【发布时间】:2015-12-11 15:16:36
【问题描述】:

我想将数据通过管道传输到交互式命令中,并将交互式命令的输出作为另一个命令的输入接收。

例如,我希望能够执行以下操作:

echo "Zaphod" | hello.sh | goodbye.sh

输出如下:

再见,赞法德

这是我最初的尝试,但我遗漏了一些东西 ;-) 我实际上希望 hello.sh 从列表中进行选择。

hello.sh

echo Please supply your name
read NAME
echo "HELLO $NAME"

goodbye.sh

MSG=$*
if [ -z "$1" ]
then
  MSG=$(cat /dev/stdin)
fi
echo "BYE $MSG"

编辑:通过“从事物列表中选择”,我想我是在暗示我的真实用例,它从标准输出中获取任何东西,让我选择一个选项,并将其传递给其他东西的标准输入...例如:

ls /tmp | select_from_list | xargs cat

将允许我列出 /tmp/ 中的文件,以交互方式选择一个,然后对文件的内容进行分类。

所以我的“select_from_list”脚本实际上是这样的:

#!/bin/bash
prompt="Please select an option:"
options=( $* )
if [ -z "$1" ]
then
  options=$(cat /dev/stdin)
fi

PS3="$prompt "
select opt in "${options[@]}" "Quit" ; do 
    if (( REPLY == 1 + ${#options[@]} )) ; then
        exit

    elif (( REPLY > 0 && REPLY <= ${#options[@]} )) ; then
        break

    else
        echo "Invalid option. Try another one."
    fi
done    
echo $opt

【问题讨论】:

  • 看起来很合理。你试过了吗? “从事物列表中选择”是什么意思?
  • 嘿!感谢您的反馈...我确实尝试过,但没有成功。它跳过了交互部分 - 我在我的问题中添加了一些关于“从事物列表中选择”的意思的更多信息......
  • 这真的是同一个问题:stackoverflow.com/questions/5843741/…
  • @JeffY - 我试过了,但它不起作用 - 它只是出于某种原因挂起,没有向我显示输入......(ls /tmp/ &amp;&amp; cat) | select_from_list。我在bashzsh 都试过了
  • hello.sh 的标准输入连接到管道,而不是 tty。从/dev/tty 阅读,或查看stackoverflow.com/a/1992967/1944784 了解如何耗尽标准输入,然后重新打开阅读。

标签: bash zsh


【解决方案1】:

感谢4ae1e1,我想出了如何做我想做的事 - 具体来说,如何让我的select_from_list 例程工作:

所以现在我可以这样做了:

ls /tmp/ | select_from_list | xargs cat

/tmp 中选择一个文件并将其分类。

select_from_list

#!/bin/bash
prompt="Please select an item:"

options=()

if [ -z "$1" ]
then
  # Get options from PIPE
  input=$(cat /dev/stdin)
  while read -r line; do
    options+=("$line")
  done <<< "$input"
else
  # Get options from command line
  for var in "$@" 
  do
    options+=("$var") 
  done
fi

# Close stdin
0<&-
# open /dev/tty as stdin
exec 0</dev/tty

PS3="$prompt "
select opt in "${options[@]}" "Quit" ; do 
    if (( REPLY == 1 + ${#options[@]} )) ; then
        exit

    elif (( REPLY > 0 && REPLY <= ${#options[@]} )) ; then
        break

    else
        echo "Invalid option. Try another one."
    fi
done    
echo $opt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    相关资源
    最近更新 更多