Я не уверен, что это самое чистое решение, но мне оно помогло:
#!/bin/bash
LOG=/var/tmp/log
(
# lots of commands
#...
) 2>&1 | tee $LOG
Хотя @sebasth предложил лучшее решение:
#!/bin/bash
LOG=/var/tmp/log
exec &> >(tee $LOG)
#...
С помощью ответа роаймы у меня наконец получилось:
Я создал 3 разных скрипта в/usr/local/bin
:
ds4led
#!/bin/bash
function float_to_int() {
echo $1 | cut -d. -f1 # or use -d, if decimals separator is,
}
function setrgb() {
LED=$(echo "$1" | egrep -o '[[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4}\.[[:xdigit:]]{4}')
[[ -z "$LED" || ! -d "/sys/class/leds/$LED:global" ]] && exit
BRIGHTNESS=0.2
POWER=$(cat "/sys/class/power_supply/sony_controller_battery_$2/capacity")
GREEN=$(float_to_int $(echo "($POWER*255/100*$BRIGHTNESS)" | bc -l))
RED=$(float_to_int $(echo "((255 - $POWER*255/100)*$BRIGHTNESS)" | bc -l))
BLUE=0
echo $RED > /sys/class/leds/$LED:red/brightness
echo $GREEN > /sys/class/leds/$LED:green/brightness
echo $BLUE > /sys/class/leds/$LED:blue/brightness
}
if [ "$#" -ne 2 ]
then
while read -r line; do
linesplit=($line)
LEDINPUT=${linesplit[0]}
POWERINPUT=${linesplit[1]}
setrgb $LEDINPUT $POWERINPUT
done < /tmp/ds4led
else
setrgb $1 $2
fi
ds4led _запись
#!/bin/bash
/usr/local/bin/ds4led $1 $2
echo $1 $2 >> /tmp/ds4led
ds4led _удалить
#!/bin/bash
sed "\!$1!d" /tmp/ds4led --in-place
Мой /etc/udev/rules.d/20-ds4.rules
файл:
ACTION=="add", KERNEL=="event28", ATTRS{uniq}=="00:1f:e2:e5:c3:2e" RUN+="/usr/local/bin/ds4led_write '%p' 00:1f:e2:e5:c3:2e"
ACTION=="remove", KERNEL=="event28", ATTRS{uniq}=="00:1f:e2:e5:c3:2e" RUN+="/usr/local/bin/ds4led_remove '%p'"
sudo crontab -e
* * * * * /usr/local/bin/ds4led
Пояснение:
При каждом подключении контроллера Dualshock 4 его серийный номер и идентификатор батареи записываются в файл /tmp/ds4led
. При подключении сценарий ds4led
вызывается напрямую именно с этими идентификаторами, чтобы мгновенно установить для полосы RGB правильный цвет. После этого каждую минуту запускается crontab, который проверяет этот файл в /tmp/ds4led
на наличие подключенных устройств и выполняет процедуру полосы RGB. Всякий раз, когда контроллер отключается, его запись в файле удаляется.
udev -правила:Поскольку каждое подключение контроллера Dualshock 4 генерировало около 8 триггеров udev из-за моего грубого фильтра, я попытался найти событие udev, которое срабатывало бы только один раз за одно подключение. В сумме каждое из этих устройств сработало :
./devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input67 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input68 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input66 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input67/mouse3 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input66/js0 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input68/event27 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input66/event28 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input67/event26 00:1f:e2:e5:c3:2e
Я просто выбрал «event28» в качестве фильтра, так как оно появляется только один раз и имеет какое-то отношение к джойстику контроллера. (Не забывайте, что каждый контроллер Dualshock состоит из сенсорной панели и дополнительных эмулируемых устройств. ). Однако я не уверен, что такое «event28».
Мне кажется, вы пытаетесь решить не ту проблему. Подсистема udev
сообщает, когда устройство подключено (и, если вы внимательны, когда оно отключено ). С другой стороны, подсистема cron
будет запускать процесс на регулярной основе.
Итак, соедините их вместе и используйте udev
, чтобы включить или отключить переключатель, который позволяет сценарию cron
выполнять свои действия.
На тривиальном уровне это может быть что-то вроде этого (и нет, я особо не рекомендую файл флага в /tmp
, если только вы не защитите его с разрешениями и владельцем)
Удев
ACTION=="add" [...] RUN+="touch /tmp/.ds4led_on"
Крон-скрипт
#!/bin/bash
#
[[ -f "/tmp/.ds4led_on" ]] || exit 0
#...Code to perform the update...