1

I've written a small program that toggles whether a device is enabled, mostly to run from a hotkey to enable/disable the touchpad since my hands always hit it while typing. I have it using notify-send to create a dialog box, however all I can currently do is say

device $1 has been enabled

The output of xinput list looks like :

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Atmel Atmel maXTouch Digitizer            id=10   [slave  pointer  (2)]
⎜   ↳ ETPS/2 Elantech Touchpad                  id=14   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Power Button                              id=8    [slave  keyboard (3)]
     ↳ Sleep Button                             id=9    [slave  keyboard (3)]
    ↳ USB2.0 HD UVC WebCam                      id=11   [slave  keyboard (3)]
    ↳ Asus WMI hotkeys                          id=12   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=13   [slave  keyboard (3)]

Is there any easy way to reliably get ETPS/2 Elantech Touchpad or USB2.0 HD UVC WebCam? A regex won't correctly match unless I look for the ↳ character, something in between, then multiple spaces, but is that a valid character for a regex?

Edit : The script is simple so I've included it, it's called with a device number (would be cool if I could also toggle_device touchpad but that's a later problem)

#!/bin/bash 

DEVICE_ENABLED=`xinput list-props $1 | grep "Enabled" | awk '{print $NF}'`

if [ "$DEVICE_ENABLED" == "1" ] #disable if it's enabled 
    then
    xinput set-prop $1 "Device Enabled" 0
    notify-send "Device $1 has been disabled"
else
    xinput set-prop $1 "Device Enabled" 1
    notify-send "Device $1 has been enabled"
fi
Brydon Gibson
  • 1,179
  • 3
  • 11
  • 22
  • 1
    Consider `--list --name-only` – Charles Duffy Sep 19 '16 at 17:17
  • and btw, you've got some quoting bugs; see http://shellcheck.net/ – Charles Duffy Sep 19 '16 at 17:18
  • The program works as is, but I'll give that a check, thanks. Probably should have checked the xinput manpage – Brydon Gibson Sep 19 '16 at 17:19
  • not xinput-specific bugs, general-purpose shell bugs. `$1` and `"$1"` behave differently -- not all the time, but in enough cases for it to matter. – Charles Duffy Sep 19 '16 at 17:19
  • `awk '/Enabled/ { print $NF }'` would put both the `grep` and the `awk` into a single pipeline element, btw. – Charles Duffy Sep 19 '16 at 17:21
  • Also, `[ "$foo" == "bar" ]` should be `[ "$foo" = "bar" ]` -- see [the POSIX `test` specification](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html); `=` is the only defined string comparison operator, so in using `==` you're relying on a bashism. (If you want a bash-extended test, better to use `[[ ]]` and get *all* the extensions, rather than using `[ ]` and having code that *looks* POSIX-compatible but isn't without more care). – Charles Duffy Sep 19 '16 at 17:22
  • Thanks for the comments guys, I always mess up my bash-isms. I ended up grepping for the device, getting the line number, and pulling that line out of `xinput -list --name-only`. Probably isn't the best but it works. Charles, I can't find any info on `$1` vs `"$1"`, google doesn't really take them as search terms, do you have any sources? – Brydon Gibson Sep 19 '16 at 20:12
  • Sure -- it's not specific to positional arguments, but general to *all* parameter expansions. See for instance [BashPitfalls #2](http://mywiki.wooledge.org/BashPitfalls#cp_.24file_.24target), and [the BashGuide section on quoting](http://mywiki.wooledge.org/BashGuide/Practices#Quoting). – Charles Duffy Sep 19 '16 at 20:17
  • [tripleee's answer to "When to wrap quotes around a variable"](http://stackoverflow.com/a/27701642/14122) is also worth reading. – Charles Duffy Sep 19 '16 at 20:20
  • ...and if you pasted your original code into http://shellcheck.net/ (as I suggested above), it would have linked you [here](https://github.com/koalaman/shellcheck/wiki/SC2086). – Charles Duffy Sep 19 '16 at 20:21
  • Okay so the only issue is the expansion, and nothing else? I thought you were specifically targeting `$1` vs `"$1"`. I agree with double quoting variables in this case. – Brydon Gibson Sep 19 '16 at 20:26
  • Yes, the unquoted expansion was what I was referring to. – Charles Duffy Sep 19 '16 at 20:34

1 Answers1

5

In practice, yes, you can do that.

arrow=$'\xe2\x86\xb3'
while IFS= read -r line; do
  if [[ $line = *"$arrow"* ]]; then
    content=${line#*"$arrow"}  # delete everything before the arrow
    content=${line%%$'\t'*}    # delete everything after first tab
    echo "Found content: $content"
  fi
done < <(xinput --list)

That said, it's easier to call xinput --list --name-only, and not need to filter.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441