read builtin不适用于管道

时间:2017-05-09 20:51:51

标签: bash io stdin

我想问用户确认从标准输入读取(显示输出[Y / n])。如果提供了一些参数,或者没有提供任何参数但是有一些输入,则它可以正常工作。但是,如果某些数据通过管道传输到脚本,则无法确认。

#!/bin/bash

output_file=$(mktemp)

cleanup() {
    rm -f "$output_file"
}

trap cleanup 0 1 2 3 15

if [ $# -gt 0 ]; then
    while [ $# -gt 0 ]; do
        echo "$1" >> "$output_file"
        shift
    done
else
    while read -r line; do
        echo "$line" >> "$output_file"
    done
fi

while true; do
    read -p "Display output? [Y/n]" response
    if [ -z "$response" ]; then
        break
    fi

    case $response in
        [Yy]*) break;;
        [Nn]*) exit;;
    esac
done

less "$output_file"

阻止read -p工作的原因是什么?应该采取什么措施来提供一致的行为?

2 个答案:

答案 0 :(得分:1)

如果脚本从标准输入读取所有内容,那么read -p将会得到什么?如果输入不是“交互设备”,则可能无法提示。 (又名终端)。你检查过read的Bash手册页了吗?它说:

  

-p prompt
  在尝试读取任何输入之前,显示提示,不带尾随换行符。仅当输入来自终端时才会显示提示。

当您的输入来自管道时,它不是来自终端。

答案 1 :(得分:1)

read命令从标准输入读取输入。如果从管道输入标准,则读取从管道中查找其数据,而不是从终端查找。

在大多数平台上,您可以通过直接从tty设备重定向读取命令的输入来解决此问题,如:

read -p "Display output? [Y/n]" response </dev/tty