I have written this script to toggle my touchpad (I will be keybinding it), but it's not working.  Why is this code not working?  And how can I accomplish this function more elegantly?


if [ "synclient | grep TouchpadOff | grep -o -E '[0-9]+'" ]
        synclient TouchpadOff=0
        notify-send "Touchpad Enabled"
        synclient TouchpadOff=1
        notify-send "Touchpad Disabled"

When you write

 if [ "some string or other" ]

the [ operator doesn't run some string or other, it just sees a non-empty string and says that is a true value.

You want

 if [ "`synclient | grep TouchpadOff | grep -o -E '[0-9]+'`" ] 

or the more modern

if [ "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" ]

but there is really no need to see if the command produces a string as grep produces an exit code so

if synclient | grep TouchpadOff | grep -q -E '[0-9]+'

should do what you want. I don't know the output format of synclient, but I would expect you could combine the two greps into one without too much effort.

  • 1
    To combine both grep: synclient | grep -oP '\s*TouchpadOff\s*=\s*\K[0-9]+' – NotAnUnixNazi Jun 29 '19 at 21:32
  • @Isaac Is this because you know the output format of synclient, or is this a guess? – icarus Jun 30 '19 at 2:41
  • 1
    I do know the output of synclient. I am not guessing. – NotAnUnixNazi Jun 30 '19 at 3:32

icarus gave a pretty good answer.  Your question is hard to answer because you don’t explain exactly what the script is supposed to be doing, so we are forced to reverse-engineer it (and guess what you are thinking).

icarus guessed that you are looking to see whether the output from synclient includes a line that contains “TouchpadOff” and a number.

I guess that you are assuming / expecting that the output from synclient includes a line that contains “TouchpadOff” and a number, and you are looking to see whether that number is 0.

If icarus guessed correctly, stop reading.

If I guessed correctly, we can adapt the penultimate (second-to-last) command in icarus’s answer as follows:

if [ "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" != 0 ]

(to test whether the number is zero) and this should be fairly portable.  But there may be a couple of shorter ways:

  • If you’re using bash, you can do

    if (( "$(synclient | grep TouchpadOff | grep -o -E '[0-9]+')" ))

    using the ((expression)) syntax.  Problems with this include:

    • It’s not POSIX-compliant, and so behavior in shells other than bash will have to be looked at on a case-by-case basis.
    • If the output from the command is null, it is treated as 0.


  • If you know more about what the output from synclient looks like than you are showing, you can write a smarter grep.  For instance, if you’re fairly certain that the output from synclient will contain a line that contains a string that looks like TouchpadOff = number, where number is a non-negative integer with no leading zero (i.e., it might be 0, 1, or 42, but not 01, 0.5, or off), and there might or might not be space(s) before and/or after the =, then you can do

    if ! synclient | grep -q 'TouchpadOff[[:space:]]*=[[:space:]]*0'

    In some versions of grep (e.g., GNU grep), you can shorten that to

    if ! synclient | grep -q 'TouchpadOff\s*=\s*0'

    I added the ! to reverse the truth value of the command.  grep -q 'TouchpadOff…=…0' will (obviously) succeed if it finds TouchpadOff = 0 — but, if my guess is correct, you want to do the

    synclient TouchpadOff=0

    command if the current value is not zero.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.