命令在读取时不输出?

问题描述:

我有一个相当奇怪的问题。我无法弄清楚它为什么会发生或如何解决它。命令在读取时不输出?

的脚本:

#!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上的任何工作。

+0

SO的主题。试试XDA Devs – Simon 2013-02-20 22:43:21

+0

@Simon这是一个脱离话题吗?它可能使用android特定的命令,但这是一个编程问题,考虑到我遇到的问题。 – GermainZ 2013-02-20 22:47:17

+0

对不起,我无法帮助这个特殊的shell arcana,但是对于框架良好的问题+1显示出相当大的工作量。继续发帖。祝你好运! – shellter 2013-02-21 01:51:21

我觉得没有使线缓冲 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 
+0

即使没有使用adb的“--line-buffered” (和Ubuntu),但是当我尝试使用Android的没有'-line-buffered'的shell时,就会出现同样的问题(不像你说的那样支持它)。 – GermainZ 2013-02-21 12:41:39

+0

如果您尝试保存稍后重现的事件列表,则使用主机可能是更好的解决方案。 – 2013-02-21 21:53:19

+0

整个想法是在设备上使用它(例如直接与其他应用程序一起使用,例如: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 
+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)

不客气:-)