如何从管道读取用户输入?

Igo*_*nko 10 shell pipe shell-script user-input

假设我有一个以confirmation.sh以下内容命名的文件:

#!/bin/bash
echo -n "Are you sure [Y/n]? "
read line
case "$line" in
    n|N) echo "smth"
        ;;
    y|Y) echo "smth"
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

我想通过以下方式运行这个脚本:

cat confirmation.sh | sh
Run Code Online (Sandbox Code Playgroud)

我看到Are you sure [Y/n]?了,剧本被打断了。有什么问题?

Gra*_*eme 10

正如其他人所说,这是因为stdinofsh已被重定向为从管道读取,它没有像通常那样连接到终端。您可以做的一件事是使用/dev/tty强制脚本从终端读取。例如:

#!/bin/sh

read -p "Are you sure [Y/n]?" line </dev/tty
case "$line" in
  y|Y) echo "confirmed"
    ;;
  *) echo "not confirmed"
    ;;
esac
Run Code Online (Sandbox Code Playgroud)

通常,只有在您特别想阻止人们编写输入脚本时才会这样做,例如:

echo Y | sh confirmation.sh
Run Code Online (Sandbox Code Playgroud)

即使用户可能希望Y在提示符下自动输入,这仍会从终端读取。对于需要密码的程序来说,这是很常见的。