Ali*_*jid 4 unix bash shell dialog
我正在尝试使用dialog在bash脚本中创建目录的命令从输入框中获取用户输入。目前,我有以下代码:
rm -f ans.txt
dialog --title "Create Directory" --inputbox "Enter the directory name:" 8 40 2>ans.txt
val=$(<ans.txt)
mkdir $val
Run Code Online (Sandbox Code Playgroud)
它可以工作,但是需要创建(和删除)临时文件。是否可以dialog在$val不使用临时文件的情况下直接从中存储用户输入?
基本上,您将使用命令替换将命令的输出获取到变量中。像这样:
date=$(date)
Run Code Online (Sandbox Code Playgroud)
它将date命令的输出写入变量$date。
但是,如果我们使用dialog dialog命令尝试相同的操作:
user_input=$(dialog --title "Create Directory" --inputbox "Enter the directory name:" 8 40)
Run Code Online (Sandbox Code Playgroud)
我们得到一个空白屏幕!为什么会这样?
说明:
dialog输出输出在stderr上的用户输入,因为ncurses已使用stdout来更新屏幕。如果不使用输出重定向,则命令替换会将命令的stdout返回到变量中-意味着ncurses的输出不会在屏幕上显示。但是,如果您键入某些内容(键入时看不到任何内容):
test<enter>
Run Code Online (Sandbox Code Playgroud)
文本test将出现在屏幕上。发生这种情况是因为它将被写入stderr,并且stderr仍指向当前终端。
注意:您可能希望在其中输入ncurses,$user_input但$user_input在命令之后为空。我认为发生这种情况是因为dialog将检查它的输出是否要发送到tty,否则不会输出任何东西。(尚未验证)
解:
我们可以使用I / O重路由来交换stderr和stdout。我们将把stderr转换成stdout并将用户输入写入变量,但另一方面将stdout转换成stderr,这将使ncurses输出到屏幕:
3>&1 1>&2 2>&3 3>&-
Run Code Online (Sandbox Code Playgroud)
简而言之:执行命令后,3>&1打开一个指向stdout的新文件描述符,将stdout 1>&2重定向到stderr,将stderr 2>&3指向stdout并3>&-删除文件描述符3。
这给了我们最终的命令:
user_input=$(\
dialog --title "Create Directory" \
--inputbox "Enter the directory name:" 8 40 \
3>&1 1>&2 2>&3 3>&- \
)
mkdir "$user_input"
Run Code Online (Sandbox Code Playgroud)