Reputation: 23
I have some simple shell code that will execute in the console, but not in a script. Here's an account of my lack of progress.
I'm trying to isolate the xinput device number of my touch screen. These lines work at the console:
% NAME="Atmel maXTouch Digitizer"
% DEVICE=`xinput | grep "$NAME" | grep -o "id=[0-9]+" | tr -d id=`
% echo Device found: $DEVICE
Device found: 12
In a script those exact lines produce nothing:
% touchscreen
Device found:
This one-liner produces the same value:
% echo `xinput | grep "Atmel maXTouch Digitizer" | grep -o "id=[0-9]+" | tr -d id=`
12
In a script, the one-liner also produces only a blank line, which eliminates bad quoting as a possible cause.
To clarify what's going on, I broke the code up. At the console, all is golden:
% NAME="Atmel maXTouch Digitizer"
% LINE=`xinput | grep "$NAME"`
% echo $LINE
⎜ ↳ Atmel Atmel maXTouch Digitizer id=12 [slave pointer (2)]
% PART=`echo $LINE | grep -o "id=[0-9]+"`
% echo $PART
id=12
% DEVICE=`echo $PART | tr -d id=`
% echo Device found: $DEVICE
Device found: 12
In a script it gets as far as the first grep, but no further:
% touchscreen
⎜ ↳ Atmel Atmel maXTouch Digitizer id=12 [slave pointer (2)]
Device found:
If there was any strange subshell stuff going on, I'd expect the first grep not to work either.
An alternative to the backtick syntax still works at the console:
% NAME="Atmel maXTouch Digitizer"
% LINE=$(xinput | grep "$NAME")
% echo $LINE
⎜ ↳ Atmel Atmel maXTouch Digitizer id=12 [slave pointer (2)]
% PART=$(echo $LINE | grep -o "id=[0-9]+")
% echo $PART
id=12
% DEVICE=$(echo $PART | tr -d id=)
% echo Device found: $DEVICE
Device found: 12
...but not in a script:
% touchscreen
⎜ ↳ Atmel Atmel maXTouch Digitizer id=12 [slave pointer (2)]
Device found:
The same alternative syntax with the one-liner also works at the console, but not in a script.
I'm running zsh on Arch Linux. I have tested this with both #!/bin/zsh
and #!/bin/bash
, with identical results. I'm flummoxed.
Upvotes: 2
Views: 996
Reputation: 18419
The pattern you are using only works as expected if you use grep
with the option -E
to enable interpretation as an extended regular expression. Without -E
the +
has to be quoted with a \
: `"grep -o "id=[0-9]+".
So using
grep -Eo "id=[0-9]+"
should solve the immediate problem.
The reason it works on the command line but not in a script is most likely that grep
is actually an alias vor grep -E
(and maybe some other options) when using the commandline but the actual grep
command in the script. You can check this by running type grep
.
While aliases can be used in scripts just as well as on the command line, they always have to be defined in the same context. This can happen either directly on the command line or in the script or by setting it in the appropriate configuration files.
For interactive shells this usually happens in $ZDOTDIR/.zshrc
(most likely ~/.zshrc
). But when using scripts only the configuration files /etc/zshenv
and $ZDOTDIR/.zshenv
are read (as they are for any other zsh instance for that matter).
If the alias is defined just in ~/.zshrc
it will not be available for scripts.
That all being said, you do not actually need to use grep
or tr
here. xinput
can do all you need on its own:
NAME="Atmel maXTouch Digitizer"
xinput list --id-only $NAME
##If you are not using zsh you may have to quote $NAME (it also works for zsh)
xinput list --id-only "$NAME"
And even that is probably not needed, as xinput
can use the name of the device instead of the id in most situations.
Upvotes: 1