如何将数据传输到交互式bash脚本并将输出传输到另一个命令?

5

我希望将数据导入到一个交互式命令中,并将交互式命令的输出作为另一个命令的输入接收。

例如,我想要像下面这样做:

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

希望输出结果如下:

BYE HELLO Zaphod

以下是我的初步尝试,但是我还缺少一些内容;-) 我实际上想让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"

编辑:通过“从事物列表中选择”,我想我暗示了我的真实用例,即从stdout中获取任何内容,并让我选择一个选项,然后将其传递给其他东西的stdin…例如:

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

看起来还不错。你试过了吗?你所说的“从一列东西中选择”是什么意思? - chepner
嘿!感谢您的反馈……我尝试了一下,但它没有起作用。它跳过了交互部分——我在我的问题中添加了更多关于“从列表中选择”的信息…… - Brad Parks
这实际上是与以下问题相同:https://dev59.com/V2025IYBdhLWcg3wtoVA - Jeff Y
@JeffY - 我试过了,但它不起作用 - 由于某些原因它只是挂起了,没有显示给我输入.... (ls /tmp/ && cat) | select_from_list。我在bashzsh中都尝试过。 - Brad Parks
1
hello.sh 的标准输入已连接到管道,而不是 tty。请从 /dev/tty 读取,或参见 https://dev59.com/FkvSa4cB1Zd3GeqPbhh7#1992967 了解如何耗尽 stdin 然后重新打开以进行读取。 - 4ae1e1
1个回答

3
感谢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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接