当我 curl 存储在我的网络服务器上的脚本时,它会无休止地回显我编写的提示,直到我发送 ^c。我所做的只是一个简单的curl https://server/test.sh | bash
。这是通过管道运行的代码
while true
do
read -r -p "[Y/n] " input
case $input in
[yY][eE][sS]|[yY])
echo "y"
break
;;
[nN][oO]|[nN])
echo "n"
break
;;
*)
echo "y/n"
;;
esac
done
答案1
简单来说
您可能期望read
当它在没有管道的情况下运行并等待用户输入时会以相同的方式行事...但它不会,因为它的 STDIN 与匿名管道绑定,并且唯一通常预期的输入是通过该管道传入的输入。
那么,为什么当不再有输入通过匿名管道并且该管道实际上已经关闭时,它会在循环中立即并反复返回?
这很可能是因为通过封闭的管道read
接收作为其 STDIN 并在每次 while 循环迭代时返回...您可以使用例如重现此过程:EOF
echo 'while :; do read -r -p "Y/y" i; echo "${i}$(date)"; done' | bash
一个解决方法是使用bash
自己的流程替代语法<(...)
如下:
bash <(echo 'while :; do read -r -p "Y/y" i; echo "${i}$(date)"; done')
因此,您可以做这样的事情:
bash <(curl https://server/test.sh)
详细
退出状态: 返回代码为零,除非文件结尾遇到,读取超时 (在这种情况下大于 128),则发生变量赋值错误, 或者向 -u 提供了无效的文件描述符作为参数。
测试并比较EOF
退出状态:
Ctrl以+结尾D(将导致EOF
):
$ read input; echo "Exit code for EOF with Ctrl+D is: $?"
Exit code for EOF with Ctrl+D is: 1
正在读取空文件(将导致EOF
):
$ touch emptyfile
$ read input < emptyfile; echo "Exit code for EOF with reading an empty file is: $?"
Exit code for EOF with reading an empty file is: 1
从封闭的管道读取:
$ echo 'read input; echo "Exit code for EOF when reading from a pipe is: $?"' | bash
Exit code for EOF when reading from a closed pipe is: 1
在没有( 的bash
管道之后隔离的退出代码read
以供参考):
$ echo 'echo "Exit code for bash alone after a pipe: $?"' | bash
Exit code for bash alone after a pipe: 0