Существует ли это: xterm bash в окне фрейма на заказ?

Вопрос или проблема

Существует ли стиль для [xterm + bash-скриптов, команд] внутри пользовательской рамки?

Мне бы хотелось этот стиль, смотрите пример:

╭─────────────────────────┤text title1├────────────────────────╮
│                                                              │
│text, команда, скрипт, if else, echo,  cat, sed, любая команда │
├──────────────────────────────────────────────────────────────┤
│text, команда, скрипт, if else, echo, ca t, sed, любая команда │
│text, команда, скрипт, if else, echo, cat , sed, любая команда │
│text, команда, скрипт, if else, echo, cat,  sed, любая команда │
├──────────────────────────────────────────────────────────────┤
├─────────────────────────┤text title2├────────────────────────┤
│text, команда, скрипт, if else, echo, cat,  sed, любая команда │
╰──────────────────────────────────────────────────────────────╯

шрифт: Моноширинный

В дополнение к тому, что сказал Стефан говорил, уже существуют программы, которые рисуют рамки вокруг вывода программ, хотя они часто довольно специфичны для использования:

cowsay:

$> echo 'Добро пожаловать в Шир!' | cowsay
 ______________________________________
/ Добро пожаловать в Шир!             \
\ Только для партийных дел.            /
 --------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

pandoc:

$> echo 'Сообщение для пользователя\nДобро пожаловать в Шир! Только для партийных дел.\nБольше текста.' | pandoc -f tsv -tgfm
| Заголовок сообщения                        |
|--------------------------------------------|
| Добро пожаловать в Шир! Только для партийных дел. |
| Больше текста.                             |

Обратите внимание, что на самом деле не так много магии, чтобы создать что-то самостоятельно.

Например, если вы хотите напечатать заголовок

╭─────────────────────────┤text title1├────────────────────────╮

в скрипте, вы сделаете что-то вроде

print_n_chars () {
  local n=$1
  local char=$2
  printf "${char}"'%.s' $(seq 1 ${n})
}
print_title () {
  local linelength=$1
  local text="┤$2├"
  local textlength=${#text}
  local leftpad=$(( (linelength - textlength - 2) / 2 ))
  local rightpad=$(( (linelength - textlength - 2) - leftpad ))
  printf '╭%s%s%s╮\n' "$(print_n_chars ${leftpad} "─")" "${text}" "$(print_n_chars ${rightpad} "─")"
}
print_text () {
  local linelength=$1
  shift
  for line in "$@"; do
    printf "│%$((linelength - 2))s│\n" "${line}"
  done
}

title="text title1"
text="Добро пожаловать в Шир! Только для партийных дел."
print_title 50 "${title}"
print_text 50 "${text}"

Шрифты в терминальных эмуляторах всегда моноширинные.

Получение такого вывода в скрипте оболочки — это просто вопрос ввода его буквально, например, как:

#! /bin/sh -
cat << 'EOF'
╭─────────────────────────┤text title1├────────────────────────╮
│                                                              │
│text, команда, скрипт, if else, echo,  cat, sed, любая команда │
├──────────────────────────────────────────────────────────────┤
│text, команда, скрипт, if else, echo, ca t, sed, любая команда │
│text, команда, скрипт, if else, echo, cat , sed, любая команда │
│text, команда, скрипт, if else, echo, cat,  sed, любая команда │
├──────────────────────────────────────────────────────────────┤
├─────────────────────────┤text title2├────────────────────────┤
│text, команда, скрипт, if else, echo, cat,  sed, любая команда │
╰──────────────────────────────────────────────────────────────╯
EOF

В zsh, используя флаги расширения параметров l[width][text1][text2] и r[width][text1][text2] (в сочетании с m, чтобы они учитывали ширину отображения символов), для выполнения выравнивания:

#! /bin/zsh -
width=64
   header() print -rC1 '╭'${(ml[width/2-1][─][┤]r[width/2-1][─][├])^@}'╮'
     body() print -rC1 '|'${(ml[width/2-1]r[width/2-1])^@}'|'
    ruler() print -rC1 "├${(ml[width-2][─])}┤"
midheader() print -rC1 '├'${(ml[width/2-1][─][┤]r[width/2-1][─][├])^@}'┤'
   footer() print -rC1 "╰${(ml[width-2][─])}╯"

header 'text title1'
body '' some text ''
ruler
body '' 'more text' 'and more' ''
midheader 'text title2'
body '' 'some last text' ''
footer

Что дает:

╭─────────────────────────┤text title1├────────────────────────╮
|                                                              |
|                             some                             |
|                             text                             |
|                                                              |
├──────────────────────────────────────────────────────────────┤
|                                                              |
|                           more text                          |
|                           and more                           |
|                                                              |
├─────────────────────────┤text title2├────────────────────────┤
|                                                              |
|                        some last text                        |
|                                                              |
╰──────────────────────────────────────────────────────────────╯

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

Имея скрипт закодированным в UTF-8 и заменив cat на iconv -f UTF-8, вы сможете гарантировать, что рамки будут нарисованы правильно в локали пользователя, если ее таблица символов имеет эти символы для рисования рамок.

В zsh вы можете заменить литерал ╭─╮├┤╰╯│ на соответствующую $'\uXXXX', где XXXX — это десятичный код символа в шестнадцатеричном формате (\u256D\u2500\u256E\u251C\u2524\u2570\u256F\u2502, соответственно), который zsh развернет в соответствующую кодировку в локали пользователя (и выдаст ошибку “символ не в диапазоне” в тех локалях, где эти символы отсутствуют).

Прежде чем UTF-8 стал общепринятым, обычным методом для рисования рамок было переключение терминального эмулятора на альтернативную кодировку.

После tput smacs (set mode alternate char set; tput rmacs для возврата, хотя вам может понадобиться tput enacs, чтобы включить его сначала) в большинстве терминалов символы такие как `afgijklmnopqrstuvwxyz{|}~ становятся ◆▒°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·, и для тех, которые этого не делают, возможность терминала acsc дает перевод. См. раздел Графика линий в справочном мануале terminfo(5) для получения подробной информации. Использование этих методов сделает вывод совместимым с большим количеством терминалов и локалей, не использующих UTF-8, но это более сложная задача в скрипте оболочки без использования специальных приложений для рисования рамок, таких как dialog или tbl, или терминальных веб-браузеров, таких как elinks или w3m, которые могут вывести отрисованную форму HTML-таблицы.

Снова, использование zsh делает это намного проще, чем в bash, так как zsh имеет встроенный интерфейс terminfo и более удобные ассоциативные массивы.

Те же функции header, body… в zsh, используя эти методы, могут быть написаны:

#! /bin/zsh -
zmodload zsh/terminfo || exit

typeset -A c=( ${(s[])terminfo[acsc]} )

# ┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│
# jklmnopqrstuvwx
width=64
((  pad = width - 2 ))
(( lpad = pad / 2 + $#terminfo[rmacs] ))
(( rpad = pad / 2 + $#terminfo[smacs] ))
 left=$terminfo[rmacs]       right=$terminfo[smacs] line=$c[q]
hleft=$c[u]$terminfo[rmacs] hright=$terminfo[smacs]$c[t]

   header() print -rC1 -- $terminfo[smacs]$c[l]${(mpl[lpad][$line][$hleft]r[rpad][$line][$hright])^@}$c[k]$terminfo[rmacs]
     body() print -rC1 -- $terminfo[smacs]$c[x]${(mpl[lpad][ ][$left]r[rpad][ ][$right])^@}$c[x]$terminfo[rmacs]
    ruler() print -rC1 -- "$terminfo[smacs]$c[t]${(mpl[pad][$line])}$c[u]$terminfo[rmacs]"
midheader() print -rC1 -- $terminfo[smacs]$c[t]${(mpl[lpad][$line][$hleft]r[rpad][$line][$hright])^@}$c[u]$terminfo[rmacs]
   footer() print -rC1 -- "$terminfo[smacs]$c[m]${(mpl[pad][$line])}$c[j]$terminfo[rmacs]"

header 'text title1'
body '' some text ''
ruler
body '' 'more text' 'and more' ''
midheader 'text title2'
body '' 'some last text' ''
footer

Ответ или решение

Существует ли возможность реализации вывода xterm с bash в пользовательском окне?

Введение

В вашей просьбе представлено требование отобразить текст и команды, выполняемые в оболочке bash, в заданном стиле с использованием терминала xterm внутри пользовательского интерфейса. Конкретно, вам требуется создать структуру, напоминающую графические рамки, в которые будут помещены выводимые команды и текст.

Возможности реализации

Существует несколько способов достижения желаемого оформления вывода в терминале xterm. Основные из них включают в себя:

  1. Использование стандартных символов для рисования рамок: В bash и zsh можно легко программировать вывод, используя символы для рисования рамок. Например, символы «─», «│», «┼» и другие могут быть использованы для формирования заголовков и разделителей.

  2. Использование специализированных инструментов: Существуют утилиты, такие как cowsay и dialog, которые могут создавать рамки вокруг текстовых сообщений или командных выводов. Эти инструменты достаточно гибкие и могут быть адаптированы под разные задачи.

  3. Создание собственных скриптов: Вы можете написать свои bash- или zsh-скрипты, использующие принты и функции для форматирования вывода в требуемом стиле. Например, используя функцию в bash, вы можете создать текст формата:

    print_title() {
       echo "╭─────────────────────────┤$1├────────────────────────╮"
    }

    И затем вызвать её с необходимым текстом.

Пример реализации в bash

Вот пример скрипта, который демонстрирует, как можно реализовать вывод в заданном вам стиле:

#!/bin/bash

print_n_chars() {
  local n=$1
  local char=$2
  printf "${char}"'%.s' $(seq 1 ${n})
}

print_title() {
  local line_length=$1
  local title_text="┤$2├"
  local text_length=${#title_text}
  local left_padding=$(( (line_length - text_length - 2) / 2 ))
  local right_padding=$(( (line_length - text_length - 2) - left_padding ))
  printf '╭%s%s%s╮\n' "$(print_n_chars ${left_padding} "─")" "${title_text}" "$(print_n_chars ${right_padding} "─")"
}

print_text() {
  local line_length=$1
  shift
  for line in "$@"; do
    printf "│%$((line_length - 2))s│\n" "${line}"
  done
}

# Пример использования
print_title 50 "text title1"
print_text 50 "text, command, script, if else, echo, cat, sed, any command"

Вывод и шрифты

Терминал xterm использует моноширинные шрифты по умолчанию, что делает текст визуально симметричным и удобным для восприятия. Это важно для отображения графических элементов, таких как рамки. Убедитесь, что ваш терминал настроен на использование поддерживаемых кодировок, таких как UTF-8, чтобы избежать проблем с несовместимостью символов.

Заключение

Возможности реализации стиля вывода xterm с использованием bash доступны и разнообразны. Используя предложенные выше методы, вы можете создать привлекательное и удобочитаемое оформление для командного вывода. Экспериментирование с кастомизацией и выводом текстов может не только улучшить визуальную привлекательность, но и сделать взаимодействие пользователя с терминалом более приятным.

Оцените материал
Добавить комментарий

Капча загружается...