是否可以在一个 TTY 中从另一个 TTY 运行对话/whiptail 脚本?

是否可以在一个 TTY 中从另一个 TTY 运行对话/whiptail 脚本?

对我来说,这个问题的起源是,在安装基于 Centos 的自定义发行版时,能够%pre从 kickstart 文件中的脚本中运行 whiptail 命令。但是,在 Anaconda 中观察到的行为可以通过任何 Linux 系统的虚拟终端轻松重现。

要在 Anaconda 中将 whiptail 命令作为 kickstart%pre脚本运行,必须切换 TTY 并在这个新 TTY 中执行该命令。关于如何执行此操作的主流建议是:

%pre
exec </dev/tty6 >/dev/tty6 2>/dev/tty6
chvt 6

# then execute your command, for example:
whiptail --inputbox "Enter some text..." 10 30

# switch back to the original TTY
chvt1
exec </dev/tty1 >/dev/tty1 2>/dev/tty1
%end

使用此方法,whiptail 对话框可以在新 TTY 中正确呈现,但是无法与对话框进行任何交互 - 例如,按tab,而不是在文本输入、“确定”和“取消”元素之间切换,实际上是在文本输入框中插入一个制表符。同样,使用箭头键会导致在对话框中写入转义序列:

在此处输入图片描述

使用 python snack(使用与 whiptail 相同的库 - libnewt)和 dialog 时也会观察到这种行为。

当然,我可以使用交互式 shell 脚本,而不是使用 whiptail,但我只是想知道是否有人对为什么会出现这种行为有任何建议,因为我认为让它工作的唯一要求是正确重定向输入和输出流。

总结

我有兴趣创建一个包含whiptail/dialog命令的脚本,该脚本可以在一个TTY中执行,并且脚本的输出/输入可以发送到/来自不同的TTY。

答案1

这对我有用(Anaconda,Fedora 20):

%pre --log=/tmp/ks_pre.log
#!/bin/bash

# Backup fds in temporal ones
exec {STDOUTBACK}>&1
exec {STDERRBACK}>&2

# Go to current terminal for pre% section
exec 1>>/dev/pts/0
exec 2>>/dev/pts/0

# Show message
whiptail --yesno 'Do you like StackOverflow?' --yes-button 'Yes' --no-button 'No' 10 70
if [ $? = 1 ]
then
    echo 'User sucks' >> /tmp/ks_pre.log
else
    echo 'User rocks' >> /tmp/ks_pre.log
fi

# Restore fds
exec 1>&$STDOUTBACK
exec 2>&$STDERRBACK

# Close temporal fds
exec {STDOUTBACK}>&-
exec {STDERRBACK}>&-

%end

可能的问题:

  1. 你为什么要用/dev/pts/0

    因为从 Anaconda 控制台我发现了哪个设备被用作 中运行的脚本的标准输入pre% section。我猜,根据 RedHat 和 Fedora 版本,可能是另一个。但很容易找出哪个适合您的情况。

  2. exec {STDOUTBACK}>&1和事物是什么exec {STDOUTBACK}>&-

    去阅读man bash并搜索相关REDIRECTION部分,您可以找到以下内容:

每个重定向前面可以加一个文件描述符编号,但也可以加一个 {varname} 形式的单词。在这种情况下,对于除 >&- 和 <&- 之外的每个重定向运算符,shell 将分配一个大于 10 的文件描述符并将其分配给 varname。如果 >&- 或 <&- 前面加有 {varname},则 varname 的值定义要关闭的文件描述符。

答案2

这应该是一条评论,但是......

您必须操作 stdin、stderr 和 stdout 以便 whiptail 输出到变量。

x=`whiptail  --inputbox "hello" 10 40  3>&1 1>&2 2>&3`

将输出放入 /tmp/x:

whiptail  --inputbox "hello" 10 40  3>/tmp/x 1>&2 2>&3

相关内容