只有一个/dev/stdin
,read
它将从使用它的任何地方读取它(默认情况下)。
解决方案是使用其他文件描述符而不是1(/dev/stdin
)。
从等效的代码(以bash表示)到您发布的[1](如下所示),
只需添加0</dev/tty
(例如)以读取“真实” tty:
while read a b c
do read -p "Enter a number: " d 0</dev/tty # 0<&2 is also valid
echo "$a -> $b -> $c and ++> $d"
done <<<"$(echo -e '1 2 3\n4 5 6')"
执行时:
$ ./script
Enter a number: 789
1 -> 2 -> 3 and ++> 789
Enter a number: 333
4 -> 5 -> 6 and ++> 333
其他替代方法是使用0<&2
(这可能看起来很奇怪,但有效)。
请注意,从/dev/tty
(from 0<&2
)读取将绕过脚本的stdin,这不会从echo中读取值:
$ echo -e "33\n44" | ./script
其他解决方案
需要的是将一个输入重定向到其他fd(文件描述符)。
在ksh,bash和zsh中有效:
while read -u 7 a b c
do printf "Enter a number: "
read d
echo "$a -> $b -> $c and ++> $d"
done 7<<<"$(echo -e '1 2 3\n4 5 6')"
或者,使用exec:
exec 7<<<"$(echo -e '1 2 3\n4 5 6')"
while read -u 7 a b c
do printf "Enter a number: "
read d
echo "$a -> $b -> $c and ++> $d"
done
exec 7>&-
在sh中起作用的解决方案(<<<
不起作用):
exec 7<<-\_EOT_
1 2 3
4 5 6
_EOT_
while read a b c <&7
do printf "Enter a number: "
read d
echo "$a -> $b -> $c and ++> $d"
done
exec 7>&-
但这可能更容易理解:
while read a b c 0<&7
do printf "Enter a number: "
read d
echo "$a -> $b -> $c and ++> $d"
done 7<<-\_EOT_
1 2 3
4 5 6
_EOT_
1更简单的代码
您的代码是:
echo -e "1 2 3\n4 5 6" |\
while read a b c;
do
echo "$a -> $b -> $c";
echo "Enter a number: ";
read d ;
echo "This number is $d" ;
done
一个简化的代码(用bash表示)是:
while read a b c
do #0</dev/tty
read -p "Enter a number: " d ;
echo "$a -> $b -> $c and ++> $d";
done <<<"$(echo -e '1 2 3\n4 5 6')"
如果执行,将打印:
$ ./script
1 -> 2 -> 3 and ++> 4 5 6
这只是表明var d正在从同一读取/dev/stdin
。