Как передать данные интерактивному сценарию bash и передать вывод другой команде?

Я хотел бы передать данные в интерактивную команду и получить вывод интерактивной команды в качестве ввода для другой команды.

Например, я хотел бы иметь возможность сделать что-то вроде следующего:

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

и иметь вывод:

ПОКА ПРИВЕТ Зафод

Вот мой первоначальный взгляд на это, но я что-то упускаю ;-) На самом деле я бы хотел, чтобы hello.sh выбирал из списка вещей.

привет.sh

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

до свидания.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

person Brad Parks    schedule 11.12.2015    source источник
comment
Выглядит разумно. Ты пробовал это? Что вы подразумеваете под выбором из списка вещей?   -  person chepner    schedule 11.12.2015
comment
Привет! спасибо за отзыв... Я попробовал, и это не сработало. Он пропускает интерактивную часть - я добавил немного больше информации о том, что я имею в виду под выбором из списка вещей на мой вопрос....   -  person Brad Parks    schedule 11.12.2015
comment
Это действительно тот же вопрос, что и: « title = «как я могу передать начальный ввод в процесс, который затем будет интерактивным»> stackoverflow.com/questions/5843741/   -  person Jeff Y    schedule 11.12.2015
comment
@JeffY - я пробовал это, но это не работает - оно просто зависает по какой-то причине, не показывая мне входные данные.... (ls /tmp/ && cat) | select_from_list. Пробовал и в bash и в zsh   -  person Brad Parks    schedule 11.12.2015
comment
стандартный ввод hello.sh подключен к каналу, а не к tty. Прочтите /dev/tty или см. stackoverflow.com/a/1992967/1944784, как исчерпать стандартный ввод, а затем снова открыть его для чтения.   -  person 4ae1e1    schedule 11.12.2015


Ответы (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
person Brad Parks    schedule 22.12.2015