gnu screen - получить список заголовков окон

gnu screen - получить список заголовков окон

Как получить информацию (заголовок, время создания, видимое содержимое) об окнах в сеансе экрана? Мне нужно сделать это в скрипте, поэтому я не ищу сочетания клавиш или интерактивные команды.

list-windowsБыло бы здорово что-то вроде tmux .

решение1

В соответствии сэта темав screen-users такая функциональность реализована в screen. Видимо, у меня недостаточно новая версия, чтобы это работало, но это должно работать в последних версиях screen.[Редактировать]Я только что попробовал с последней версией git, она работает, даже если это не задокументировано вscreen -h

screen -Q windows
screen -Q select my_window

Первое появление опции -Qбыло вэто совершить.

решение2

Попробуйте последовательность Ctrl-a wсогласно инструкцииздесь.

Лично я использую файл .screenrc, который постоянно сохраняет эту информацию внизу экрана (как на панели задач Windows). Мой конфиг экрана (~/.screenrc) выглядит так:

hardstatus on
hardstatus alwayslastline
hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a "

решение3

В GNU Screen сочетание клавиш по умолчанию для получения списка всех окон (и выбора одного из них для переключения) следующее:

C-a "

решение4

Наконец то я понял!

Мне нужно сделать это в сценарии...

Введение

Я открыл 5 окон, закрыл окно#2и открыл файл с проблемным именем4$ esp32.pdfв окне#3...

screen -Q windows
0$ man screen  1*$ user@host$  3$ pdfread: 4$ esp32.pdf  4-$ root@server#

Эта строка почти непригодна для использования! (См. далее мойболее быстрая функция.)

Мое решение, как функция

Хотелось бы получить правильный список открытых окон, даже если заголовки некоторых окон содержат строки вроде ...2*$...:

Вот функция поиска существующего номера окна, от 0до 99(по умолчанию).

getWinList() {
    if [[ $1 == -v ]]; then
        local -n _outar="$2";shift 2
        else local _outar
    fi
    _outar=()
    local _string _pointer _maxid=${1:-99}
    case $_maxid in
        '' | *[!0-9]* )
            cat <<EOUsage
Usage:
    $FUNCNAME [-v <varname>] [INT]
       -v varname  Populate array "$varname" with window list
       [INT]       Optional last ID to check for existence (default 99)
EOUsage
            return 1
            ;;
    esac
    for ((_pointer=0;_pointer<=_maxid;_pointer++)); do
        _string=$(screen -p $_pointer -Q title) &&
            printf -v _outar[_pointer] %s "$_string"
    done
    printf >&2 '\e[A\n\e[K'
    [[ ${_outar[@]@A} != declare\ -a\ _outar=* ]] ||
        for _pointer in ${!_outar[@]};do
            printf '  %6s: %s\n' "[$_pointer]" "${_outar[_pointer]}"
        done
}

Вы можете использовать -vопцию сохранения результата вмножествопеременную и добавьте необязательное количество окон для проверки:

Я открыл 5 окон, закрыл окно №2 и открыл файл с проблемным именем в окне 3...

getWinList
     [0]: man screen
     [1]: user@host$
     [3]: pdfread: Little 4$ esp32.pdf
     [4]: root@server#

getWinList 3
     [0]: man screen
     [1]: user@host$
     [3]: pdfread: 4$ esp32.pdf


getWinList -v array 10                                          
declare  -p array
declare -a array=([0]="man screen" [1]="user@host\$" [3]="pdfread: 4\$ esp32.pdf" [4]="root@server#")

Быстрее, но менее надежно:

Как есть

  • на основе выходной мощности screen -Q windowsон ограничен токомокноширина,
  • основано нарегулярное выражение, любой заголовок окна, соответствующий этомуповторноможет привести к поломке результирующего массива.
getWinListFast() {
    if [[ $1 == -v ]]; then
        local -n _outar="$2";shift 2
        else local _outar
    fi
    _outar=()
    if [[ $1 ]]; then
            cat <<EOUsage
Usage:
    $FUNCNAME [-v <varname>]
       -v varname  Populate array "$varname" with window list
EOUsage
            return 1
    fi
    . <(screen -Q windows |
            sed '
                :a;
  s/^\(.*\n\|\)\([0-9]\+\)[*!-]*$ \(\([^ ]\| [^ ]\)\+\)\(  \(.*\)\|\) *$/\1[\2]="\3"\n\6/;
                ta;
                s/[|$]/\\&/g;
                s/.*/_outar=(&)\n/')
        printf >&2 '\e[A\n\e[K'
    [[ ${_outar[@]@A} != declare\ -a\ _outar=* ]] ||
        for _pointer in ${!_outar[@]};do
            printf '  %6s: %s\n' "[$_pointer]" "${_outar[_pointer]}"
        done
}

Связанный контент