1

Источник этого вопроса, для меня, заключается в том, что при установке пользовательского дистрибутива на основе Centos можно запустить команду whiptail в сценарии %pre из файла кикстарта. Однако поведение, наблюдаемое в Anaconda, может быть легко воспроизведено через виртуальные терминалы любой системы Linux.

Для запуска команды whiptail в Anaconda в качестве сценария 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 вместо переключения между элементами ввода текста, элементами "Ok" и "Cancel" фактически вставляет вкладка в поле ввода текста. Точно так же использование клавиш со стрелками приводит к тому, что escape-последовательности записываются в диалоге:

Такое поведение также наблюдается при использовании python snack (использует ту же библиотеку, что и whiptail - libnewt) и диалоговом окне.

Конечно, я мог бы просто использовать интерактивный сценарий оболочки, а не использовать whiptail, но мне было просто интересно, есть ли у кого-нибудь какие-либо предложения относительно того, почему это поведение наблюдается, так как я бы подумал, что единственными требованиями для получения этой работы будут правильно перенаправить входной и выходной потоки.

TL; DR

Я заинтересован в создании сценария, содержащего команды whiptail/dialog, которые могут быть выполнены в одном TTY и получать / вводить сценарий в / из другого TTY.

2 ответа2

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}. В этом случае для каждого оператора перенаправления, кроме> & - и <& -, оболочка выделит дескриптор файла больше 10 и присвоит его переменной varname. Если> & - или <& - предшествует {varname}, значение var-name определяет закрываемый дескриптор файла.

0

Это должен быть комментарий, но ...

Вы должны манипулировать 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .