我正在编写一个bash从文件中读取的脚本。从文件中读取后,我想提示用户输入,并从终端读取它。
这是我的代码的摘录:
while IFS=',' read -r a b c
do
#a, b, c are read in from file
data1=$a
data2=$b
data3=$c
#later in the loop
#answer should be read in from the terminal
echo "Enter your answer to continue:"
read answer
done
Run Code Online (Sandbox Code Playgroud)
但是,目前我认为脚本认为我正在尝试从与、和answer相同的输入文件中读入。如何在文件输入和终端输入之间切换?abc
如果您的标准输入已从文件重定向(即,您是使用 调用的./yourscript <file),则使用/dev/tty从终端读取:
#!/bin/bash
exec 3</dev/tty || {
echo "Unable to open TTY; this program needs to read from the user" >&2
exit 1
}
while IFS= read -r line; do # iterate over lines from stdin
if [[ $line = Q ]]; then
echo "Getting input from the user to process $line" >&2
read -r answer <&3 # read input from descriptor opened to /dev/tty earlier
else
echo "Processing $line internally"
fi
done
Run Code Online (Sandbox Code Playgroud)
如果您想exec 3</dev/tty从顶部跳过(/dev/tty在脚本开头仅打开一次,允许稍后使用 TTY 进行读取<&3),那么您可以改为编写:
read -r answer </dev/tty
Run Code Online (Sandbox Code Playgroud)
...每次要从终端执行读取时打开它。但是,您希望确保对循环中在这些情况下失败的情况进行错误处理(例如,如果此代码是从 cron 作业运行的,则调用时将命令ssh作为参数传递,并且no ,或没有-tTTY 的类似情况)。
或者,考虑在 stdin 以外的描述符上打开文件 - 在这里,我们使用文件描述符 #3 作为文件输入,并假设调用为./yourscript file(stdin 指向终端):
#!/bin/bash
filename=$1
while IFS= read -r line <&3; do # reading file contents from FD 3
if [[ $line = Q ]]; then
echo "Getting input from the user to process $line" >&2
read -r answer # reading user input by default from FD 0
else
echo "Processing $line internally" >&2
fi
done 3<"$filename" # opening the file on FD 3
Run Code Online (Sandbox Code Playgroud)