我看到了以下shell脚本。我想我对它在做什么有了基本的了解,但我仍然不明白使用这么多重定向和文件描述符的目的是什么?例如exec 3>&1,do something 2>&1 1>&3和exec 3>&-。
#-Open file descriptor (fd)
exec 3>&1
#-Create a form and then store data to $VALUES variable
VALUES=$(dialog \
--keep-tite \
--ok-label "Submit" \
--backtitle "Linux User Managment" \
--title "Useradd" \
--form "Create a new user" \
15 50 0 \
"Username:" 1 1 "$user" 1 10 10 0 \
"Shell:" 2 1 "$shell" 2 10 15 0 \
"Group:" 3 1 "$groups" 3 10 8 0 \
"HOME:" 4 1 "$home" 4 10 40 0 \
2>&1 1>&3)
# close fd
exec 3>&-
# display values just entered
echo "$VALUES"
Run Code Online (Sandbox Code Playgroud)
你能告诉我为什么它们是必要的吗?是因为dialog正在使用的实用程序吗?我问是因为我从来没有见过人们用简单的命令来做这件事,比如ls等等。
exec 3>&1
ls 2>&1 1>&3
exec 3>&-
Run Code Online (Sandbox Code Playgroud)
通常dialog通过stdout文件描述符1向用户显示其对话框,从stdin文件描述符0读取用户的击键,并将用户填写的值输出到stderr文件描述符2。
引入额外文件描述符的原因是通过$(command…)替换读取值(与反引号相同)。命令替换接受dialog…发送给它的任何内部命令(在本例中为)并将其stdout填充到外部命令中(在本例中为VALUES=…)。
该2>&1重定向品牌dialog发送的字段值的stdout,在那里他们将被捕获到VALUES。因此,dialog需要一个不同的文件描述符来向用户显示对话框。该exec 3>&1复制原始stdout文件描述符。也就是说,在该命令之后,文件描述符 3 和文件描述符 1 引用同一个文件——原始stdout. 该1>&3重定向品牌dialog显示其对话框到原来的stdout。
换句话说,引入文件描述符 3 的原因是暂时“保存” stdout。