Почему не делает работы xsetwacom от udev?

find плюс grep

Объединение find пересекать каталоги рекурсивно с grep.

Если поддержка -print0 и -0 компилируются в, затем можно использовать xargs вызвать grep для многих файлов сразу ¹:

find /some/dir -type f -print0 | xargs -0 grep -H PATTERN

Если Ваши имена файлов являются ручными (никакой пробел или \'"), Вам не нужно -print0/-0:

find /some/dir -type f |xargs grep -H PATTERN

Если Вы имеете не подходящий xargs, необходимо будет вызвать grep на каждом имени файла отдельно:

find /some/dir -type f -exec grep -H PATTERN {} \;

Если Вы имеете find но это не имеет -exec, и Ваши имена файлов являются ручными (никакие новые строки или \[*?), и Ваши замены команды поддержек оболочки (т.е. пепел и не тишина), и нет слишком многих файлов для рассмотрения, можно генерировать список имен файлов с find и передача, что как аргумент grep.

set -f
IFS='
'
grep PATTERN $(find /some/dir -type f)
set +f

Если существует много файлов, можно использовать a for цикл по всем файлам (все еще только для пепла из-за замены команды).

set -f
IFS='
'
for x in $(find /some/dir -type f); do
  grep -H PATTERN "$x"
done
set +f

¹ Нет -exec … + на Busybox.

Без find

Если Вы не имеете find, это сложно. Если Ваш Busybox имеет пепел и достойное test, можно записать рекурсивный обход каталога в оболочке.

traverse () {
  d=$1; shift
  for x in "$d"/* "$d"/.[!.]* "$d"/..?*; do
    if test -f "$x"; then
      "$@" "$x"
    elif test -d "$x"; then
      traverse "$x" "$@"
    fi
  done
}
traverse /some/dir

Но если Вы не имеете find, Вы находитесь, вероятно, в очень ограниченной системе, где оболочка является тишиной, которая испытывает недостаток в функциях. Можно моделировать функции с eval. Я предположу, что Вы имеете test; если Вы не делаете, обнаружение каталогов является возможным, но болезненным.

command='grep -H PATTERN'
traverse='
  for x in "$d"/* "$d"/.[!.]* "$d"/..?*; do
    if test -f "$x"; then
      '"$command"' "$x"
    elif test -d "$x"; then
      d="$x"
      eval "$traverse"
    fi
  done
'
d=/some/dir
eval "$traverse"
8
22.02.2013, 20:11
5 ответов

Существует довольно легкое обходное решение, можно добавить что-то вроде этого к Вашему xorg.conf (или файл в xorg.conf.d, поскольку я сделал):

anthony@Watt:/etc/X11/xorg.conf.d$ cat 55-local-wacom.conf 
Section "InputClass"
       Identifier "Wacom Left Handed"
       MatchDriver "wacom"
       Option "Rotate" "half"
EndSection

Проверьте wacom (4) страница справочника для деталей всех опций, которые можно установить.

(В теории можно использовать MatchProduct для отдельного конфигурирования сенсорной панели, пера, средства стирания, и т.д., но когда я попробовал это некоторое время назад, это вызвало Xorg к segfault. То же, если я пытался пустить в ход их. Но Вы не делаете ни одного из этого..., и возможно ошибка исправлена теперь.)

3
27.01.2020, 20:12
  • 1
    Ничего себе, после так многих поиск с помощью Google я никогда не сталкивался с этим. Я upvoted Ваш ответ. Я испытаю его, когда я буду работать. Любая определенная причина 55? Я всегда использую идею, что "бесчисленные записи обрабатываются в последний раз, поэтому лучше пропускать числа для пользовательских записей". –  Redsandro 24.02.2013, 19:33
  • 2
    @Redsandro /usr/share/X11/xorg.conf.d/50-wacom.conf 50 в моей системе, таким образом, я выбрал 55 для прибытия после нее. Не уверенный, который даже имеет значение. –  derobert 25.02.2013, 15:30
  • 3
    Этот ответ предоставляет полезную информацию, но не отвечает на исходный вопрос. Что, если Вы включаете свое устройство Wacom USB после того, как запустил X-сервер? дурак –  Lqueryvg 26.09.2015, 13:18
  • 4
    @Lqueryvg InputClass относится к замененным в горячем режиме устройствам, таким образом, он должен работать затем также. –  derobert 26.09.2015, 17:09
  • 5
    @derobert, благодарит ответить. Я не понял, что InputClass работал на замену в горячем режиме также. У меня есть некоторые события кнопки, которые я отображаю использование xsetwacom, и я хотел бы инициировать их, если я заменяю свой планшет в горячем режиме после того, как X запустился. Я дам этому попытку. Спасибо! –  Lqueryvg 26.09.2015, 17:34

Когда Вы включаете устройство:

  1. Linux обнаруживает устройство и создает запись устройства на основе правил udev.
  2. X-сервер обнаруживает устройство.

Вы не можете работать xsetwacom перед этапом 2. Ваш сценарий перестал работать, потому что Вы выполняете его на этапе 1, когда X еще не знает устройство.

Можно установить некоторые настройки с gnome-settings-daemon. Я полагаю, что это получает свое уведомление о новом устройстве через D-шину, но я не знаю то, на что похоже D-событие-шины. Попытайтесь шпионить за шиной с dbus-monitor.

2
27.01.2020, 20:12
  • 1
    I upvoted Ваш ответ для получения дополнительной информации но я не уверен, что это корректно по следующей причине: Я пытался использовать sleep с набором секунд. При включении, работы планшета после меньше, чем секунда, поэтому к тому времени, когда выполняются команды, устройство уже обнаруживается и используемо X. Но тем не менее это не работает? –  Redsandro 24.02.2013, 19:26

Работает, если создать два файла, один оберточный скрипт вызывается udev, который, в свою очередь, вызывает реальный конфигурационный скрипт в фоновом режиме. Конфигурационный скрипт должен немного поспать, чтобы X11 успел сделать свою работу. Вот настройка, которую я использую:

Оберточный скрипт, вызываемый udev (/usr/local/bin/setupwacom.sh):

#!/usr/bin/env bash
/usr/local/bin/setupwacom-post-X11.sh &

Конфигурационный скрипт, вызываемый оберточным скриптом (/usr/local/bin/setupwacom-post-X11.sh):

#!/usr/bin/env bash
sleep 2
export XAUTHORITY=/home/adrian/.Xauthority
export DISPLAY=:0
# Put your xsetwacom commands here, for example: 
xsetwacom --set "Wacom Intuos S Pad pad" Button 1 "key +ctrl +shift e"
2
27.01.2020, 20:12

Ни один из ответов здесь не сработал для меня, и параметры, которые я хотел установить, не могли быть указаны в xorg.conf :

$ xsetwacom -x get 'Wacom Intuos PT S Pad pad' button 1 
Button: Actions are not supported by xorg.conf. Try shell format (-s) instead.

В итоге мне пришлось запускать скрипт с помощью службы systemd, запускаемой правило udev:

$ cat /etc/udev/rules.d/99-wacom.rules
SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="056a", ENV{ID_MODEL_ID}=="0302", TAG+="systemd"

Идентификатор поставщика и модели можно найти при запуске lsusb с подключенным устройством.

Чтобы перезагрузить правила udev:

$ udevadm control --reload-rules
$ udevadm trigger

TAG + = "systemd" позволяет другим службам systemd (системе или пользователю) зависеть от устройства (регистрирует его как устройство, см. man systemd.device ). Чтобы узнать название устройства, запустите udevadm monitor и подключите планшет. Я получаю

UDEV  [2918.098423] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 (usb)
...

Чтобы проверить, что systemd подхватывает его, выполните

$ systemctl status /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/
● sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.device - CTH-480 [Intuos Pen & Touch (S)]
   Loaded: loaded
   Active: active (plugged) since Mon 2016-06-20 11:14:20 UYT; 29min ago
   Device: /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3

Итак, единицей устройства является sys-devices-pci0000: 00-0000: 00: 1d.0-usb2-2 \ x2d1-2 \ x2d1 .3.device , и его можно использовать в служебном модуле systemd

 $ cat .config/systemd/user/wacom.service    
[Service]
Type=forking
Restart=no
ExecStart=/path/to/wacom-pad-button-setup

[Install]
WantedBy=default.target
WantedBy=sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.1.device
WantedBy=sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.2.device
WantedBy=sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.device

На каждый порт USB приходится одно устройство.

Затем включите и перезагрузите устройство с помощью systemctl --user enable wacom.service и systemctl --user daemon-reload .

Скрипту еще нужно немного спящего, чтобы xsetwacom нашел устройство и установил $ DISPLAY и $ XAUTHORITY . Type = oneshot нормально работает при подключении, но не запускается, если устройство уже было подключено при загрузке компьютера. Вот почему мне нужно было использовать пользовательский сервис вместо системного, и почему в модуле также есть WantedBy = default.target . Проблема с oneshot в том, что он блокировал startx. Type = forking и Restart = no указывает systemd не ждать завершения разветвленного процесса скрипта, чтобы затем скрипт мог спать в фоновом режиме, ожидая запуска Xorg.

$ cat bin/wacom-pad-button-setup
#!/bin/rc
{
    sleep 2

    if (~ $DISPLAY ()) {
        DISPLAY=:0
        XAUTHORITY=/home/spelufo/.Xauthority
    }

    xsetwacom set 'Wacom Intuos PT S Pad pad' button 9 'button +3 -3'
    xsetwacom set 'Wacom Intuos PT S Pad pad' button 8 'button +4 -4'
    xsetwacom set 'Wacom Intuos PT S Pad pad' button 3 'button +1 -1'
    xsetwacom set 'Wacom Intuos PT S Pad pad' button 1 'button +2 -2'
} &
0
27.01.2020, 20:12

Обходной путь от derobert подходит не для всех ситуаций, (если вы не можете использовать xorg.conf ).

Предложенное Адрианом обертывание и sleepрешение почему-то у меня не работает (ubuntu 16.04 ).

Если вы добавите это в начало скрипта xsetwacom:

exec > /tmp/debug-my-script.txt 2>&1
xinput --list

Из вывода видно, что сценарий xsetwacom каким-то образом все еще выполняется до того, как xinputузнает о wacom. Независимо от того, как долго вы делаете сон.

Здесь я предлагаю другое решение/обходной путь с использованием небольшой программы в , которая проще, чем решение spelufo (, которое я не пробовал ), но требует только установки atпрограмма.(sudo apt install atдля пользователей Debian ).

Теперь измените сценарий-оболочку (Ответ Адриана )на что-то вроде этого:

#!/usr/bin/env bash
at now -f /usr/local/bin/setupwacom-post-X11.sh

atобычно используется для однократного планирования команды, например, вы можете запланировать ее на час вперед с помощью at now +1 hours -f yourscript.sh. Но поскольку вы можете добавлять только минуты/часы/дни/недели, я использовал nowбез добавления, но полагался на сон внутри скрипта xsetwacom.

2
27.01.2020, 20:12

Теги

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