读取内置不适用于管道
read builtin doesn't work with pipe
我想请用户确认从 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 "" >> "$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
的工作?应该怎么做才能提供一致的行为?
如果脚本从标准输入读取所有内容,read -p
会得到什么?如果输入不是 'interactive device'(又名终端),它可能不会提示。您是否检查了 Bash 手册页中的 read?它说:
-p
prompt
Display prompt, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal.
当您的输入来自管道时,它不是来自终端。
read
命令从标准输入读取输入。如果你有从管道馈送的标准输入,那么读取从管道而不是从你的终端查找它的数据。
在大多数平台上,您可以通过直接从 tty 设备重定向读取命令的输入来解决此问题,如:
read -p "Display output? [Y/n]" response </dev/tty
我想请用户确认从 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 "" >> "$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
的工作?应该怎么做才能提供一致的行为?
如果脚本从标准输入读取所有内容,read -p
会得到什么?如果输入不是 'interactive device'(又名终端),它可能不会提示。您是否检查了 Bash 手册页中的 read?它说:
-p
prompt
Display prompt, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal.
当您的输入来自管道时,它不是来自终端。
read
命令从标准输入读取输入。如果你有从管道馈送的标准输入,那么读取从管道而不是从你的终端查找它的数据。
在大多数平台上,您可以通过直接从 tty 设备重定向读取命令的输入来解决此问题,如:
read -p "Display output? [Y/n]" response </dev/tty