Как создать петлю перенаправления

Хотя вопрос предполагал, что Xephyr был запущен правильно (поскольку информация по этому поводу не предоставлена), я, по крайней мере, подтвердил, что qBittorrent отлично работает в Xephyr на Debian Xfce Wheezy.

На скриншоте ниже показан qBittorrent 2.9.8 в Xephyr.

qBittorrent 2.9.8 in Xephyr on Debian Xfce Wheezy

Это было протестировано на Debian Xfce Wheezy и с использованием последних пакетов libqtcore4 и xserver-xephyr , доступных на данный момент, которые аналогичны версиям, указанным в вопросе.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 7.9 (wheezy)
Release:    7.9
Codename:   wheezy

$ dpkg-query -W | grep libqt
libqt4-dbus:i386    4:4.8.2+dfsg-11
libqt4-network:i386 4:4.8.2+dfsg-11
libqt4-xml:i386 4:4.8.2+dfsg-11
libqtcore4:i386 4:4.8.2+dfsg-11
libqtdbus4:i386 4:4.8.2+dfsg-11
libqtgui4:i386  4:4.8.2+dfsg-11

$ dpkg-query -W | grep xephyr
xserver-xephyr  2:1.12.4-6+deb7u6

Определение проблемы

Единственным релевантным поиском, который я нашел, была Ошибка 71421 , сообщающая о том, что «приложения Qt5 не работают с Xephyr».

При попытке запустить какие-либо приложения Qt5 (или явно GTK3) внутри Xephyr они не работают (так как ничего не показано). GTK2 или Qt4 работают так же хорошо, как и приложения GLX (например, glxgears). Также протестирован на автономном X-сервере без запущенного DM - Qt5 отлично работает там, только внутри Xephyr они этого не делают.

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

Кроме того, не было предоставлено никакой информации о том, как приложение запускалось в Xephyr.

Вышеупомянутые приложения работают при запуске на обычном X-сервере, но когда я запускаю их в Xephyr, я вижу только рамку окна, но она пуста.

Основываясь на процитированном тексте, у меня есть еще кое-что, чтобы сомневаться: работал ли Xephyr с неверными аргументами? Или, скорее, как приложение было запущено в Xephyr от имени другого пользователя?

Если вы действительно уверены, что приложения Qt4 не работают в Xephyr, это может быть проблема, о которой не сообщалось в пакете Qt4. Но поскольку я подтвердил, что qBittorrent (на основе Qt4) отлично работает в Xephyr, это может быть проблема с «другим пользователем» или с тем, как Xephyr запускался из текущего сеанса.

Об использовании Xephyr

Это несколько онлайн-источников, которые объясняют использование Xephyr для выполнения определенных задач.

  1. Ксефир на ArchWiki. Хорошее место для начала работы с Xephyr, но мало что объясняет об обширном использовании, кроме запуска терминала или оконного менеджера в Xephyr.

  2. Не знаю, как начать работу с Ксефиром. Что я делаю не так? в списке рассылки Xorg от четверг, 23 января, 17:16:40 PST 2014. Другой способ запуска Xterm в Xephyr.

  3. Как запустить несколько рабочих столов X? на суперпользователе, спросил 22 июля '09. Один из ответов предлагал использовать Ксефир. Аналогично тому, как предложено в источнике №1.

  4. Многопользовательская конфигурация / Xephyr: Как создать мультитерминал с Xephyr в Викиучебниках.

  5. Скриншоты с нескольких X-серверов на Unix и Linux Stack Exchange, задано 21 августа 2014 года.

  6. Как: запустить firefox (и другие вещи) как отдельный пользователь с Xephyr . Кажется, это наиболее похожее использование, как указано в вопросе.

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

При этом есть что-то непонятное для понимания первого предложения «использование Xephyr для запуска приложений от имени другого пользователя, во время входа в систему как основного пользователя». В конце концов, я не создавал «другого пользователя» для тестового запуска qBittorrent в Xephyr. Возможно, кто-то другой может дать лучший ответ.

6
08.07.2016, 22:12
3 ответа

В bash это можно сделать с помощью сопроцесса (в bash плохая поддержка нескольких сопроцессов, но здесь вам нужен только один):

#!/bin/bash
set -e
coproc { while read -r line; do echo "$BASHPID read: $line";  done; }
i=0; while :; do
    echo "$BASHPID writing>> $i"
    echo $i >&"${COPROC[1]}"
    read -r line <&"${COPROC[0]}"
    echo "$BASHPID coproc produced>> $line"
    i=$((i+1))
done

или именованные каналы ( они также работают в простых оболочках POSIX):

#!/bin/bash
set -e
trap 'rm -rf "$tmpd"' EXIT
tmpd=$(mktemp -d)

mkfifo "$tmpd/p0" "$tmpd/p1"
exec 3<>"$tmpd/p0"
exec 4<>"$tmpd/p1"
rm -rf "$tmpd"

( while read -r line; do echo "$BASHPID read: $line";  done; ) <&3 >&4  &
i=0; while :; do
    echo "$BASHPID writing>> $i" 
    echo $i >&3
    read -r line <&4
    echo "$BASHPID coproc produced>> $line"
    i=$((i+1))
done 

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

Кроме того, из-за влияния каналов на планирование (запись в каналы с полным буфером канала блокирует вас, как и чтение из канала с пустым), вы можете попасть в тупик с определенными шаблонами чтения / записи.

Результаты двух приведенных выше примеров могут выглядеть следующим образом:

32435 writing>> 0
32435 coproc produced>> 32441 read: 0
32435 writing>> 1
32435 coproc produced>> 32441 read: 1
32435 writing>> 2
32435 coproc produced>> 32441 read: 2
32435 writing>> 3
32435 coproc produced>> 32441 read: 3
32435 writing>> 4
32435 coproc produced>> 32441 read: 4
4
27.01.2020, 20:27

Я не думаю, что вы можете сделать это с конвейером ( | ), но это легко сделать с помощью асинхронных процессов, которые пишут и читают друг друга.

Этот ksh93 скрипт ( bash версия ниже ) запускает два , а -циклы, которые перебрасывают число между ними, добавляя один к номеру в каждой транзакции:

while read data; do
    print $(( data + 1 ))
done |&

print -p 1

while read -p data; do
    print $(( data + 1 ))
done >&p
  1. Первый цикл запускается как сопроцесс. Он ожидает ввода на своем чтении .
  2. Число 1 дается чтению сопроцесса, чтобы начать все это.
  3. Второй цикл запускается с того же самого, что и первый цикл, но не как сопроцесс.

Запуск с включенным xtrace (и с измененным сценарием, который устанавливает PS4 , приглашение трассировки, на «&» для первого цикла, и to ">" для второго цикла, просто чтобы показать, что к чему):

$ ksh -x script.sh
& PS4='& '
> PS4='> '
> print -p 1
> 1>& p
> read -p data
& read data
& print 2
& read data
> print 3
> read -p data
& print 4
> print 5
> read -p data
& read data
& print 6
& read data
> print 7
> read -p data
(etc.)

bash также выполняет совместные процессы (ищите встроенную команду coproc ), но я меньше знаком с ними. Вероятно, вы также можете сделать это в оболочке без сопроцессов.

РЕДАКТИРОВАТЬ : Примерно так для bash :

coproc while read data; do
    echo $(( data + 1 ))
done

echo 1 >&${COPROC[1]}

while read -u ${COPROC[0]} data; do
    echo $(( data + 1 ))
done >&${COPROC[1]}

Запуск (с измененной подсказкой трассировки, как указано выше):

$ bash -x script.sh
+ PS4='& '
& PS4='> '
> echo 1
> read -u 63 data
& read data
& echo 2
> echo 3
> read -u 63 data
& read data
& echo 4
> echo 5
> read -u 63 data
& read data
& echo 6
> echo 7
> read -u 63 data
(etc.)
3
27.01.2020, 20:27

Для более сложных деревьев перенаправления файловых дескрипторов есть pipexec, который попал в репозиторий Debian.

Воистину, это ограничение синтаксиса в BASH и в Bourne-подобных оболочках в целом.

1
27.01.2020, 20:27

Теги

Похожие вопросы