使用文件输入作为 shell 脚本的标准输入不起作用

使用文件输入作为 shell 脚本的标准输入不起作用

我有以下脚本代码:

测试文件

echo "BEGIN"
while read CMD <&1; do
    [ -z "$CMD" ] && continue
    case "$CMD" in
    start)
            echo "get_start"
            ;;
    stop)
            echo "get_stop"
            ;;
    *)
            echo "get_uknown_command"
            ;;
    esac
    echo "END";
done

当我用以下方式运行它时:

$./test.sh <input.txt

我的脚本被锁定了

输入.txt

start
stop
sthh

为何我的脚本被锁定?我该如何修复?

顺便说一句:如果我手动输入数据,那么脚本将不会锁定。

答案1

您使用了错误的文件描述符。 1是 stdout,0是 stdin。

改变:

while read CMD <&1; do

到:

while read CMD <&0; do

它将正确地从文件中读取数据。但是,您不需要执行所有这些操作,因为read默认使用 stdin:

while read CMD; do

此外,该-u选项还可用于从特定文件描述符读取(至少在 bash 中)。因此,您也可以这样做:

while read -u 0 CMD; do

答案2

文件描述符1stdout标准输出。这意味着你重定向read的输入来自标准输出。这显然不会很好地发挥作用;几乎肯定不会有任何输入在标准输出上等待read

标准输入是文件描述符0,因此如果您在脚本的第 2 行更改<&1为,它就可以正常工作。或者干脆完全删除该部分;默认情况下从标准输入读取(这几乎是它的目的),因此无需明确告诉它从标准输入读取。<&0read

如果您想以交互方式读取某些特定输入并允许其余部分从文件重定向(或通过管道传输),您可以执行read </dev/tty

并且在 END 回显之后不需要分号语句分隔符;换行符就可以了。

相关内容