提问人:miken32 提问时间:10/1/2018 最后编辑:miken32 更新时间:10/2/2018 访问量:237
暂时停止重定向以获取用户输入
Temporarily stop redirection to get user input
问:
我有一个脚本,它使用一种非常标准的方法来将所有内容捕获到日志文件中:
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
read -rp "Prompt: " input >&6
答:
1赞
Barmar
10/2/2018
#1
问题是该函数在执行之前将输出重定向到日志文件。但是,命令替换的工作原理是运行命令,并将其输出重定向到管道,并且您正在覆盖它。因此,nput 被写入文件,而不是管道。echo "$userInput"
您需要保存输出重定向,然后还原到该保存的值,而不是将日志文件硬编码到函数中。
我还修改了您的脚本以分别保存和恢复,而不是假设它们最初指向同一事物。另外,由于使用 ,我只在函数中保存/恢复该 FD。stdout
stderr
read -p
stderr
#!/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
评论
0赞
miken32
10/2/2018
标记为已接受,但我最终会使用您关于如何正确重定向命令的评论!read
1赞
Barmar
10/2/2018
为了完整起见,我已将其添加到答案中。
上一个:(可选)将参数传递给脚本中的命令
评论
input
2>&1
>"$logfile"
read -p
read -rp "Prompt: " input 2>&6