如何将数据通过管道传输到交互式 bash 脚本并将输出通过管道传输到另一个命令?
How to pipe data to interactive bash script and pipe output to another command?
我想将数据通过管道传输到交互式命令中,并将交互式命令的输出作为另一个命令的输入接收。
例如,我希望能够执行以下操作:
echo "Zaphod" | hello.sh | goodbye.sh
并且输出为:
BYE HELLO Zaphod
这是我最初的破解方法,但我遗漏了一些东西 ;-) 我实际上想要列表中的 hello.sh 到 select。
hello.sh
echo Please supply your name
read NAME
echo "HELLO $NAME"
goodbye.sh
MSG=$*
if [ -z "" ]
then
MSG=$(cat /dev/stdin)
fi
echo "BYE $MSG"
编辑:"select from a list of things",我想我是在暗示我的真实用例,即从 stdout 获取任何内容,让我选择一个选项,然后将其传递给其他内容的 stdin。 .. 例如:
ls /tmp | select_from_list | xargs cat
将允许我列出 /tmp/ 中的文件,交互式地选择一个,然后 cat 文件的内容。
所以我的 "select_from_list" 脚本实际上是这样的:
#!/bin/bash
prompt="Please select an option:"
options=( $* )
if [ -z "" ]
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
感谢 4ae1e1,我想出了如何做我想做的事 - 具体来说,如何让我的 select_from_list
例行工作:
所以现在我可以做这样的事情了:
ls /tmp/ | select_from_list | xargs cat
从 /tmp
中选择一个文件并对其进行 cat。
select_from_list
#!/bin/bash
prompt="Please select an item:"
options=()
if [ -z "" ]
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
我想将数据通过管道传输到交互式命令中,并将交互式命令的输出作为另一个命令的输入接收。
例如,我希望能够执行以下操作:
echo "Zaphod" | hello.sh | goodbye.sh
并且输出为:
BYE HELLO Zaphod
这是我最初的破解方法,但我遗漏了一些东西 ;-) 我实际上想要列表中的 hello.sh 到 select。
hello.sh
echo Please supply your name
read NAME
echo "HELLO $NAME"
goodbye.sh
MSG=$*
if [ -z "" ]
then
MSG=$(cat /dev/stdin)
fi
echo "BYE $MSG"
编辑:"select from a list of things",我想我是在暗示我的真实用例,即从 stdout 获取任何内容,让我选择一个选项,然后将其传递给其他内容的 stdin。 .. 例如:
ls /tmp | select_from_list | xargs cat
将允许我列出 /tmp/ 中的文件,交互式地选择一个,然后 cat 文件的内容。
所以我的 "select_from_list" 脚本实际上是这样的:
#!/bin/bash
prompt="Please select an option:"
options=( $* )
if [ -z "" ]
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
感谢 4ae1e1,我想出了如何做我想做的事 - 具体来说,如何让我的 select_from_list
例行工作:
所以现在我可以做这样的事情了:
ls /tmp/ | select_from_list | xargs cat
从 /tmp
中选择一个文件并对其进行 cat。
select_from_list
#!/bin/bash
prompt="Please select an item:"
options=()
if [ -z "" ]
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