命令在读取时不输出?
我有一个相当奇怪的问题。我无法弄清楚它为什么会发生或如何解决它。命令在读取时不输出?
的脚本:
#!system/bin/sh
#set -x
reader() {
t2=-1
grep -v -E "add device|name:" | while IFS=' ' read -r t1 a b c d _; do
t1=${t1%%-*}
t=`expr $t1 - $t2`
if let 't > 0 && t2 > -1'; then
echo "sleep $t"
fi
printf 'sendevent %s' "${a%?}"
printf '%5d %5d %5d\n' "0x$b" "0x$c" "0x$d"
t2=$t1
done
}
let() {
IFS=, command eval [ '$(($*))' -ne 0 ]
}
countDown() {
echo 'Starting in...'
i=4
while [[ $i -gt 1 ]]; do
i=$(($i-1))
echo "$i"
sleep 1
done
printf '%s\n\n\n' 'Go!'
# echo "$*"
"[email protected]" | reader
}
clear
printf '%s >' 'Catch by [n]umber of events or [t]imeout?'
read type
case $type in
n)
printf '%s >' 'Events to catch?'
read arg
echo "Gonna catch $arg events!"
countDown getevent -t -c "$arg"
;;
t)
printf '%s >' 'Timeout (in seconds)?'
read arg
echo "Gonna catch events for $arg seconds!"
countDown timeout -t $arg getevent -t
esac
脚本的目标:
捕捉使用getevent命令的用户的交互(例如按键,屏幕抽头等),并输出一个脚本到标准输出,可用于复制这些事件。
附加信息:
getevent的输出以十六进制格式 的SendEvent接受十进制格式
预期输出:
Catch by [n]umber or by [t]imeout? n
Events to catch? > 4
Gonna catch 4 events...
Starting in...
3
2
1
Go!
sendevent /dev/input/event5 1 102 1
sendevent /dev/input/event5 0 0 0
sleep 3
sendevent /dev/input/event5 1 102 0
sendevent /dev/input/event5 0 0 0
问题:
代码运行作为经验当“n”被选中时被锁定。当选择“t”时,脚本在指定的秒数后退出。但是,它不会输出任何内容 - while循环的第一行甚至不会运行。
设置-x,这里就是我们的显示(最后几行):
+ printf %s\n\n\n Go!
Go!
+ reader
+ t2=-1
+ grep -v -E add device|name:
+ timeout -t 5 getevent -t
+ IFS = read -r t1 a b c d _
运行这个单独输出显示到标准输出(输出的应该被读取和修改while循环中):
timeout -t 5 getevent -t
有什么想法?
谢谢。
编辑:
好了,所以我认为这是一个缓冲的问题。基本上,这给出了类似的问题: getevent > output
文件获取每一堆事件的更新,但不是立即(如果没有足够的事件,可能永远不会更新)。我没有意识到Android上的任何工作。
我觉得没有使线缓冲 BusyBox中的grep
的方式,但你可以做这样的事情:
$ adb shell timeout -t 10 getevent -t | \
grep --line-buffered -v -E "add device|name:" | \
while read line; do echo "READ: $line"; done
即使没有使用adb的“--line-buffered” (和Ubuntu),但是当我尝试使用Android的没有'-line-buffered'的shell时,就会出现同样的问题(不像你说的那样支持它)。 – GermainZ 2013-02-21 12:41:39
如果您尝试保存稍后重现的事件列表,则使用主机可能是更好的解决方案。 – 2013-02-21 21:53:19
整个想法是在设备上使用它(例如直接与其他应用程序一起使用,例如:LMT Launcher,Tasker等),并与可能不运行Linux发行版的用户共享(或准备好使用Cygwin)。 – GermainZ 2013-02-21 22:11:12
这里基本上是这些东西,我从你的代码翻译的错误被错位前解决方法。替换一个命令我没有在超时分支上使用cat
,它可以在Busybox sh,dash,mksh,bash和ksh93中的示例输入正确运行。
由于如此多的关于shell和应用程序的基本知识都被打破,这并不奇怪,这是行不通的。我会确保Busybox是最新的,并查看您继续使用的算术和其他错误是否可以在其他系统上重现,并且如果此代码不起作用则报告错误。
#!/bin/sh
reader() {
t2=-1
grep -vE '^(add device|[[:space:]]+name:)' |
while IFS=' ' read -r t1 a b c d _; do
let "(t = (t1 = ${t1%%-*}) - t2) > 0 && t2 > -1" && echo "sleep $t"
printf 'sendevent %s' "${a%[[:digit:]]:}"
printf '%5d %5d %5d\n' "0x$b" "0x$c" "0x$d"
let t2=t1
done
}
let() {
IFS=, command eval test '$(($*))' -ne 0
}
countDown() {
echo 'Starting in...'
i=4
while let 'i-=1 > 0'; do
echo "$i"
sleep 1
done
printf '%s\n\n\n' 'Go!'
echo "$*"
"[email protected]" <&3 | reader
}
isDigit() {
while ! ${1+false}; do
case $1 in
*[^[:digit:]]*|'') return 1
esac
command shift
done 2>/dev/null
}
main() {
printf '%s >' 'Catch by [n]umber of events or [t]imeout?'
read type
case $type in
n)
printf '%s >' 'Events to catch?'
read arg
isDigit "$arg" || return 1
echo "Gonna catch $arg events!"
countDown getevent -t -c "$arg"
;;
t)
printf '%s >' 'Timeout (in seconds)?'
read arg
isDigit "$arg" || return 1
echo "Gonna catch events for $arg seconds!"
countDown busybox timeout -t "$arg" cat -
;;
*)
return 1
esac
}
main "[email protected]" 4<&0 <<\EOF 3<&0 <&4 4<&-
add device 1: /dev/input/event8
name: "bcm_headset"
add device 2: /dev/input/event7
name: "max8986_ponkey"
add device 3: /dev/input/event6
name: "sec_touchscreen"
add device 4: /dev/input/event5
name: "sec_keypad"
add device 5: /dev/input/event4
name: "orientation"
add device 6: /dev/input/event3
name: "accelerometer"
add device 7: /dev/input/event0
name: "proximity_sensor"
add device 8: /dev/input/event2
name: "geomagnetic_raw"
add device 9: /dev/input/event1
name: "geomagnetic"
45534-48646 /dev/input/event6: 0001 008b 00000001
45534-48646 /dev/input/event6: 0000 0000 00000000
45534-48646 /dev/input/event6: 0001 008b 00000000
45534-48646 /dev/input/event6: 0000 0000 00000000
EOF
# vim: set fenc=utf-8 ff=unix ft=sh :
输出:
$ bb --help
BusyBox v1.21.0 (2013-02-20 20:39:21 CST) multi-call binary.
Usage: bb [-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]]/FILE [ARGS]]
Unix shell interpreter
$ bb answers/countdown
Catch by [n]umber of events or [t]imeout? >t
Timeout (in seconds)? >5
Gonna catch events for 5 seconds!
Starting in...
3
2
1
Go!
busybox timeout -t 5 cat -
sendevent /dev/input/event6: 1 139 1
sendevent /dev/input/event6: 0 0 0
sendevent /dev/input/event6: 1 139 0
sendevent /dev/input/event6: 0 0 0
赋值给出错误: 'eval:arith:语法错误:“t2 = t1” eval:arith:语法错误:“(t =(t1 = 45534)-t2)> 0 && t2> -1”' 这就是说,转换实际上适用于'cat',但是当我用'getevent'或'getevent -t'替换'cat'时,同样的问题被复制(根本不输出 - 甚至不是错误)。 – GermainZ 2013-02-21 12:32:30
有同样的问题,并记住我首先在MS-DOS 3.30使用的特技,后来在Cygwin的(未超时,但更命令是对于大量的重定向问题)神奇的子弹:
timeout -t 8 getevent | more > getevent.txt
作品以及在Total Commander的外壳 与SU(未SH)
不客气:-)
SO的主题。试试XDA Devs – Simon 2013-02-20 22:43:21
@Simon这是一个脱离话题吗?它可能使用android特定的命令,但这是一个编程问题,考虑到我遇到的问题。 – GermainZ 2013-02-20 22:47:17
对不起,我无法帮助这个特殊的shell arcana,但是对于框架良好的问题+1显示出相当大的工作量。继续发帖。祝你好运! – shellter 2013-02-21 01:51:21