【发布时间】:2015-01-20 04:12:05
【问题描述】:
我有一些简单的 shell 代码将在控制台中执行,但不在脚本中。这是我缺乏进展的说明。
我正在尝试隔离我的触摸屏的 xinput 设备编号。这些行在控制台上工作:
% NAME="Atmel maXTouch Digitizer"
% DEVICE=`xinput | grep "$NAME" | grep -o "id=[0-9]+" | tr -d id=`
% echo Device found: $DEVICE
Device found: 12
在脚本中,这些确切的行不会产生任何结果:
% touchscreen
Device found:
这个单行产生相同的值:
% echo `xinput | grep "Atmel maXTouch Digitizer" | grep -o "id=[0-9]+" | tr -d id=`
12
在脚本中,单行也只产生一个空行,这排除了bad quoting这个可能的原因。
为了澄清发生了什么,我分解了代码。在控制台,一切都是金色的:
% 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
在脚本中,它会到达第一个 grep,但不会更远:
% touchscreen
⎜ ↳ Atmel Atmel maXTouch Digitizer id=12 [slave pointer (2)]
Device found:
如果有任何 strange subshell stuff 正在进行,我希望第一个 grep 也不起作用。
反引号语法的替代方法仍然适用于控制台:
% 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
...但不在脚本中:
% touchscreen
⎜ ↳ Atmel Atmel maXTouch Digitizer id=12 [slave pointer (2)]
Device found:
与单行符相同的替代语法也适用于控制台,但不适用于脚本。
我在 Arch Linux 上运行 zsh。我已经用#!/bin/zsh 和#!/bin/bash 对此进行了测试,结果相同。我很困惑。
【问题讨论】:
-
你能显示实际的脚本吗?除非我们能看到代码,否则很难说是哪里出了问题。
-
您是否在脚本顶部放置了 shebang (
#!/bin/bash)?并且您是否添加了声明export PATH=/path/to/directory/containing/xinput以便可以找到xinput? -
我认为奇怪的是为什么它可以在 shell 中工作。试试
grep -o "id=[0-9]\+"(注意反斜杠),那么它在脚本中有效吗? -
为什么不使用 -x 选项运行脚本来调试运行脚本时发生的情况。我会以
bash -x myscript.sh的身份运行脚本。 -
您对 grep 正则表达式中的转义 + 是正确的,谢谢。 @Adaephon 的详细回答在各个方面都是正确的。