如何在通过管道执行的Bash脚本中读取用户输入?
问题:管道执行Bash脚本时无法读取用户输入
现有Bash脚本test.sh内容如下:
#!/bin/bash read -p "Do you want to continue? (y/n) " yn case $yn in [yY] ) echo "Doing stuff...";; echo "Done!";; [nN] ) echo "Exiting...";; exit;; * ) echo "Invalid response";; esac
直接通过./test.sh或bash test.sh运行时一切正常,但使用管道方式执行时(比如curl -s https://<myurl>/test.sh | bash -s或本地的bash < test.sh),脚本不会打印提示语,直接输出Invalid response。原因是此时脚本的标准输入被管道内容占用,read无法从终端获取用户输入。
解决方案
1. 修正脚本的case语法错误
原脚本的case分支写法存在语法问题,echo "Done!"和exit未归属到对应分支下,会导致逻辑错误。修正后的case结构如下:
case $yn in [yY] ) echo "Doing stuff..." echo "Done!" ;; [nN] ) echo "Exiting..." exit ;; * ) echo "Invalid response";; esac
2. 让read从终端读取输入
修改read命令,强制从终端设备(/dev/tty)读取用户输入,这样即使标准输入被管道占用,也能正确获取用户输入。修改后的read命令:
read -p "Do you want to continue? (y/n) " yn < /dev/tty
完整修正后的脚本:
#!/bin/bash read -p "Do you want to continue? (y/n) " yn < /dev/tty case $yn in [yY] ) echo "Doing stuff..." echo "Done!" ;; [nN] ) echo "Exiting..." exit ;; * ) echo "Invalid response";; esac
3. 可选的替代执行方式
如果不想修改脚本,也可以先将脚本内容保存到临时文件再执行,避免管道占用标准输入:
curl -s https://<myurl>/test.sh > temp.sh && bash temp.sh && rm temp.sh
内容的提问来源于stack exchange,提问作者phil_rawlings
相关产品推荐
相关产品推荐

