我有一个脚本,该脚本使用一种非常标准的方法将所有内容捕获到日志文件中:
exec 6>&1 1>"$logFile" 2>"$logFile"
# do stuff
exec 1>&6 2>&6 6>&-
现在,我想捕获一些用户输入,但是似乎无法从函数中返回用户数据。
#!/usr/bin/env bash
function getInput() {
local userInput
# disable redirection temporarily
exec 1>&6 2>&6 6>&-
read -rp "Prompt: " userInput
# restore redirection
exec 6>&1 1>>"$logFile" 2>>"$logFile"
echo "$userInput"
}
logFile="$HOME/foo.txt"
# enable redirection to the log file
exec 6>&1 1>"$logFile" 2>"$logFile"
input=$(getInput)
exec 1>&6 2>&6 6>&-
echo "Got $input"
出现提示,我可以输入响应,但是输入没有返回到主脚本。为什么?
编辑添加的内容是,如果我从函数中删除了exec
行,则会正确读取并返回输入,但是即使我执行了以下重定向,当然也不会显示对用户的提示:{{ 1}}
答案 0 :(得分:1)
问题在于该函数在执行echo "$userInput"
之前将输出重定向到日志文件。但是,通过运行命令并将其输出重定向到管道,命令替换可以起作用,您将对此进行覆盖。结果,nput被写入文件,而不是管道。
您需要保存输出重定向,然后还原到该保存的值,而不是将日志文件硬编码到函数中。
我还修改了您的脚本,以分别保存和恢复stdout
和stderr
,而不是假设它们最初指向的是同一事物。另外,由于read -p
使用stderr
,因此我仅将FD保存/恢复到函数中。
#!/usr/bin/env bash
function getInput() {
local userInput
# disable redirection temporarily
exec 8>&2 2>&7
read -rp "Prompt: " userInput
# restore redirection
exec 2>&8 8>&-
echo "$userInput"
}
logFile="$HOME/foo.txt"
# enable redirection to the log file
exec 6>&1 7>&2 1>"$logFile" 2>&1
input=$(getInput)
exec 1>&6 2>&7 6>&- 7>&-
echo "Got $input"
但是所有这些重定向实际上都是不必要的,您可以重定向read
命令:
read -rp "Prompt: " userInput 2>&7
请注意,应该将stderr
重定向到此处,而不是stdout
; read -p
精确地使用stderr
,以便在重定向stdout
时可以使用它(在这种情况下,重定向stderr
不太常见)。