Is it possible to run a dialog/whiptail script in one TTY from another?

1

3

The origin of this question, for me, is being able to run a whiptail command in a %pre script from a kickstart file when installing a custom distribution based on Centos. However, the behaviour observed in Anaconda can easily be reproduced via the virtual terminals of any Linux system.

To run the whiptail command in Anaconda as a kickstart %pre script it is necessary to switch TTY and execute the command in this new TTY. The prevailing suggestion as to how to do this is:

%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

Using this method the whiptail dialog box is correctly rendered in the new TTY, however no interaction can take place with the dialog - for example pressing tab, rather than switching between the text entry, "Ok", and "Cancel" elements, actually inserts a tab in the text entry box. Similarly, using the arrow keys results in escape sequences being written in the dialog:

enter image description here

This behaviour is also observed when using python snack (uses the same library as whiptail - libnewt) and dialog.

Of course, I could just using an interactive shell script, rather than using whiptail, but I was just wondering if anyone had any suggestions as to why this behaviour is seen, as I would have thought that the only requirements to get this working would be to correctly redirect the input and output streams.

TL;DR

I'm interested in creating a script containing whiptail/dialog commands which can be executed in one TTY and have the output/input of the script go to/come from a different TTY.

pxul

Posted 2014-08-11T09:42:39.833

Reputation: 175

Answers

1

This worked for me (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

Possible questions:

  1. Why did you use /dev/pts/0?

    Because from the Anaconda console I found out what device was being used as stdin for the scripts running in the pre% section. I guess, it could be another one depending on the RedHat and Fedora versions. But it is really easy to find out which is the correct one for your case.

  2. What are the exec {STDOUTBACK}>&1 and exec {STDOUTBACK}>&- things?

    Go to read your man bash and search for the REDIRECTION section, where you can find the following:

Each redirection that may be preceded by a file descriptor number may instead be preceded by a word of the form {varname}. In this case, for each redirection operator except >&- and <&-, the shell will allocate a file descriptor greater than 10 and assign it to varname. If >&- or <&- is preceded by {varname}, the value of var‐ name defines the file descriptor to close.

Gooseman

Posted 2014-08-11T09:42:39.833

Reputation: 126

0

This should be a comment, but...

You have to manipulate stdin,stderr and stdout for whiptail to output to a variable.

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

This puts the output into /tmp/x:

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

user150471

Posted 2014-08-11T09:42:39.833

Reputation: 1

Perhaps my question wasn't too clear. I'm interested in creating a script containing whiptail/dialog commands which can be executed in one TTY and have the output/input of the script go to/come from a different TTY. This can be simulated by opening one virtual terminal and trying to (a) switch input/output streams and (b) switch virtual terminals from within a script. Above this is achieved by exec </dev/tty6 >/dev/tty6 2>/dev/tty6 and chvt 6 respectively. – pxul – 2014-08-13T09:00:47.293