É possível executar um script de diálogo / whiptail em um TTY de outro?

1

A origem desta questão, para mim, é ser capaz de executar um comando whiptail em um script %pre de um arquivo de kickstart ao instalar uma distribuição personalizada baseada no Centos. No entanto, o comportamento observado no Anaconda pode ser facilmente reproduzido através dos terminais virtuais de qualquer sistema Linux.

Para executar o comando whiptail no Anaconda como um script %pre do kickstart, é necessário trocar o TTY e executar o comando neste novo TTY. A sugestão predominante sobre como fazer isso é:

%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

Usando esse método, a caixa de diálogo whiptail é renderizada corretamente no novo TTY, mas nenhuma interação pode ocorrer com a caixa de diálogo - por exemplo, pressionando tab , em vez de alternar entre a entrada de texto, "Ok" e "Cancelar "elementos, na verdade, insere uma guia na caixa de entrada de texto. Da mesma forma, o uso das teclas de seta faz com que sequências de escape sejam gravadas na caixa de diálogo:

Esse comportamento também é observado quando se usa o lanche de python (usa a mesma biblioteca do whiptail - libnewt) e o diálogo.

Claro, eu poderia apenas usar um script de shell interativo, em vez de usar whiptail, mas eu estava imaginando se alguém tinha alguma sugestão sobre por que esse comportamento é visto, como eu teria pensado que os únicos requisitos para obter esse trabalhar seria redirecionar corretamente os fluxos de entrada e saída.

TL; DR

Estou interessado em criar um script contendo comandos whiptail / dialog que possam ser executados em um TTY e que a saída / entrada do script vá para / venha de um TTY diferente.

    
por pxul 11.08.2014 / 11:42

2 respostas

1

Isso funcionou para mim (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

Possíveis perguntas:

  1. Por que você usou /dev/pts/0 ?

    Como no console do Anaconda, descobri que dispositivo estava sendo usado como stdin para os scripts em execução no pre% section . Eu acho, poderia ser outro dependendo das versões do RedHat e do Fedora. Mas é muito fácil descobrir qual é a correta para o seu caso.

  2. Quais são as coisas exec {STDOUTBACK}>&1 e exec {STDOUTBACK}>&- ?

    Acesse o man bash e pesquise a seção REDIRECTION , onde você pode encontrar o seguinte:

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.

    
por 29.11.2014 / 12:14
0

Isso deve ser um comentário, mas ...

Você tem que manipular stdin, stderr e stdout para whiptail para gerar uma variável.

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

Isso coloca a saída em / tmp / x:

whiptail  --inputbox "hello" 10 40  3>/tmp/x 1>&2 2>&3
    
por 12.08.2014 / 23:09