Toggling binary values from shell — a tale of lazyness

June 15, 2013 | 4 Minute Read

Here’s today story.

I’ve changed my laptop, and I’m now using a fantastic ThinkPad x220.

I like the trackpoint, and I’m sometimes pissed off by touchpad being enables while I’m typing.

Lukily hardware on thinkpads is supported very very well, so disabling the touchpad is as easy as typing:

manu@nadia:~$ synclient TouchpadOff=0

Yeah, it’s really that simple. Of course, to enable it back, just set TouchpadOff to 1 instead. Yeah, plain simple binary values, nothing more nothing less.

So, I’ve been typing whole commands for some time now, today I wanted to see how could I automate that.

Things like theese, system related, should be automated in operating system based tools. In my case, it’s the shell, Bash. And of course, shell-based tools.

Ok, let’s move on:

manu@nadia:~$ synclient -l

will show current touchpad settings. Obviously, I’m gonna grep against its output:

manu@nadia:~$ synclient -l | grep -i touchpadoff
TouchpadOff = 0

Nice! I want to get the 0 alone. Let’s observe that result: it’s a simple key=value.

So, if we split for ‘=’, we should get a key and a value.

This is the kind of task awk is suited for:

manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F “=” ‘{print $2}’
0

Maybe you can’t see here, but there’s a whitespace before that zero.

If I was using some programming language like Perl or Python, I’d trim the string  and move on.

But wait: what I’m gonna do with that value? It’s a bit, I should flip (=~ negate) it.

Let’s dig the gnu awk documentation for string operations: the strtonum(str) function does what i need:

manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F “=” ‘{print strtonum($2)}’
0

So we got a numeric value. You could be tempted to dig the gnu awk documentation for bitwise operations and use the compl function, but it’s not going to work:

manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F “=” ‘{print compl(strtonum($2))}’
9007199254740991

Why ? Because it’s a bitwise operation, and I suppose it’s going to operate against a number which, although it’s zero, it probably encoded in 32 bit.

The right thing to do then is to operate against logic values instead of numeric ones:

manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F “=” ‘{print strtonum($2)}’
0
manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F “=” ‘{print !strtonum($2)}’
1

Well, it’s done.

Now we have to figure out how to use this value as the new value for TouchpadOff. And it’s simple:

manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F ‘=’ ‘{print strtonum($2)}’
1
manu@nadia:~$ synclient touchpadoff=`synclient -l | grep -i touchpadoff | awk -F “=” ‘{print !strtonum($2)}’`
manu@nadia:~$ synclient -l | grep -i touchpadoff | awk -F ‘=’ ‘{print strtonum($2)}’
0
manu@nadia:~$

Yeah, it’s that simple, using bash’ command substitution.

Now it’s just a matter of creating a function:

toggle_touchpad(){ synclient TouchpadOff=`synclient -l | grep -i touchpadoff | awk -F ‘=’ ‘{print !strtonum($2)}’`;}

and write it in your .bashrc.

manu@nadia:~$ synclient -l | grep -i touchpadoff
TouchpadOff = 0
manu@nadia:~$ toggle_touchpad
manu@nadia:~$ synclient -l | grep -i touchpadoff
TouchpadOff = 1
manu@nadia:~$

It’s done :)