Имеется процесс xterm, который "вставлен" в Tk-окно:
class Terminal(tk.Frame):def __init__(self, parent):
...
# Получение tty с которым будет работать терминал (грубый хак)
os.system('xterm -into %d -geometry 160x50 -sb -e "tty > /tmp/ttyinfo.txt"' % self.wid)
fp=open('/tmp/ttyinfo.txt', 'r')
self.tty=fp.readline().strip();
fp.close();
print("tty info: "+self.tty)# Открытие терминала с bash. Перед запуском bash выводится рабочий tty
os.system('xterm -into '+str(self.wid)+' -geometry 160x50 -sb -e "tty ; bash -norc" &')
Выполнение команд в этом xterm-терминале сделано двумя способами:* Через os.system().
* Через Popen+communicate.Для теста я использую две команды, которые генерируют цветной вывод:
1. ip -color addr
2. ansible-playbook ourPlaybook.yml
И вот какая проблема проявилась:* Способ запуска через os.system() всегда работает правильно. Для обеих команд вывод в xterm цветной.
* Способ запуска через Popen+communicate() правильно работает только для "ip -color addr". Но для Ansible почему-то генерируется монохромный вывод.А нужно чтобы и через Popen+communicate() правильно генерировался цветной вывод в терминал для любой команды. Потому что только этим способом можно получить stdOut + stdErr + errCode. Ведь в os.system доступен только код возврата.
Для демонстрации я сделал минимальный пример. Функции запуска выглядят так:
# Выполнение команды в терминале - вариант 1
def doCommand1(self, text) :
cmdLine="(%s) <%s >%s 2> %s" % (text, self.tty, self.tty, self.tty)
result=os.system(cmdLine)
...
return result# Выполнение команды в терминале - вариант 2
def doCommand2(self, text) :
cmdLine="%s" % (text)
resultTriada=command.run(cmdLine)
log.echo("* Результат: " +resultTriada[0])
log.echo("* Вывод ошибок: "+resultTriada[1])
log.echo("* Код возврата: "+str(resultTriada[2]))
...
# Возвращается кортеж из stdOut, stdErr, errCode
return resultTriada
Во втором случае используется метод с вызовом Popen+communicate():
class Command():# Запуск внешней программы
def run(self, cmd):
p=Popen(cmd, stdout=PIPE, shell=True)
stdOutData, stdErrData = p.communicate()
errCode=p.returncodeoutData=""
errData=""if not stdOutData is None :
outData=stdOutData.decode()if not stdErrData is None :
errData=stdErrData.decode()# Убирается последний перенос строк, чтобы в конце небыло пустой строки
outData=re.sub("\n$", '', outData)
errData=re.sub("\n$", '', errData)return(outData, errData, errCode)
В примере сделано 4 кнопки (то есть, со всеми возможными вариантами):- IP адрес (os.system)
- IP адрес (Popen)
- Ansible (os.system)
- Ansible (Popen)Первые три генерируют цветной вывод, а четвертая - монохромный.
Так вот, надо добиться, чтобы и вариант на 4-й кнопке, обязательно делал цветной вывод.
Ссылка на пример: https://files.fm/u/ex9nfywf2
Скриншот: https://i.ibb.co/FKZQYkt/screenshot-2023-04-25-15-45-51.png
(На нем видна часть цветного вывода 3-й кнопки, и монохромный вывод 4-й кнопки).
Чем ты там занимаешься, чувак? почему вместо гуя с кнопками нельзя сделать шелл-алиасы?alias a='ansible-playbook ourPlaybook.yml'
Все. Печатаешь "a" [Enter] -- и команда запустится. Не намного медленнее, чем тыкать на кнопки. Код ошибки последней команды можно показывать в PS1. Всяко гибче и удобнее.
> Чем ты там занимаешься, чувак? почему вместо гуя с кнопками нельзя сделать
> шелл-алиасы?
> alias a='ansible-playbook ourPlaybook.yml'
> Все. Печатаешь "a" [Enter] -- и команда запустится. Не намного медленнее, чем
> тыкать на кнопки. Код ошибки последней команды можно показывать в PS1.
> Всяко гибче и удобнее.Шелл-алиасы ?))) Особенно для сторонних пользователей - классная идея.))) Да и для собственного использования так себе. Забивать оперативную память мозга всяким мусором. С кнопками с гуей не нужно запоминать где что зачем.
запомнить шелл-алиас легче, чем писать программу, открывать топики в опеннете, бодаться с "цветным терминальным выводом виден в Popen". И забивается не оперативная, а долгосрочная память, поброди по dotfiles-репозиториям на гитхабе и удивись тому, как люди используют довольно остроумные алиасы и функции на все случаи жизни. Моим самым продуктивным оказалсяmdc() {
mkdir -p -- "$1" && cd -- "$1"
}Алиасы/функции также подразумевают, что ты не выходишь из консоли, захотел - сделал "a" (ansible-playbook), а захотел - быстренько вызвал совершенно другую команду, не предусмотренную гуем, -- и все это без открытия нового окна.