根据连续输出流的内容发出命令

时间:2019-10-19 12:54:27

标签: bash

此处命令:

stdbuf -oL -eL libinput debug-events \
  --device /dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event \
  | grep SWITCH_TOGGLE

返回一个连续流,侦听设备上的更改以及类似以下的字符串:

event7   SWITCH_TOGGLE     +2.65s   switch tablet-mode state 1
event7   SWITCH_TOGGLE     +4.62s   switch tablet-mode state 0

问题是,当状态更改为1时,我希望发出此命令:

systemctl start iio-sensor-proxy.service

当状态为0时,我希望发出此命令:

systemctl stop iio-sensor-proxy.service

如何将所有东西放在一起?

安德鲁·维克斯(Andrew Vickers),我什至试图执行此操作以查看是否返回了任何内容,但是什么也没有:

#!/bin/bash

stdbuf -oL -eL libinput debug-events --device /dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event | grep SWITCH_TOGGLE |
while read string; do
  echo "$string";
done

没有回声。

2 个答案:

答案 0 :(得分:2)

如何处理bash中的流输入:一些建议。

  • 使用sed代替grep:更轻,更快:

  • 使用专用的 FD 作为命令来释放 STDIN

我的样品:

DEVICE=/dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event

exec 6< <(
      exec stdbuf -oL -eL libinput debug-events --device $DEVICE |
          sed -une /SWITCH_TOGGLE/p
)

while read -u 6 foo foo mtime action target foo state; do
  if [ "$action" = "switch" ] && [ "$target" = "tablet-mode" ] ;then
    case $state in
        0 ) systemctl stop  iio-sensor-proxy.service ;;
        1 ) systemctl start iio-sensor-proxy.service ;;
    esac
  fi
done

从那里,您可以在 read 上使用STDIN进行一些交互

DEVICE=/dev/input/by-path/pci-0000:00:1f.0-platform-INT33D6:00-event

exec 6< <(
      exec stdbuf -oL -eL libinput debug-events --device $DEVICE |
          sed -une /SWITCH_TOGGLE/p
)
LIPIDS=($(ps ho pid,ppid | sed "s/ $!$//p;d"))

while :;do
  read -t 1 -u 6 foo foo mtime action target foo state &&
  if [ "$action" = "switch" ] && [ "$target" = "tablet-mode" ] ;then
    case $state in
        0 ) systemctl stop  iio-sensor-proxy.service ;;
        1 ) systemctl start iio-sensor-proxy.service ;;
    esac
  fi
  if read -t .001 -n 1 USERINPUT ;then
      case $USERINPUT in
          q ) exec 6<&- ; echo User quit.; kill ${LIPIDS[@]} ; break ;;
      esac
  fi
done

答案 1 :(得分:0)

这应该做到:

PATH