2013-02-20 96 views
2

我有一個相當奇怪的問題。我無法弄清楚它爲什麼會發生或如何解決它。命令在讀取時不輸出?

的腳本:

#!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

回答

2

我覺得沒有使線緩衝 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

2

這裏基本上是這些東西,我從你的代碼翻譯的錯誤被錯位前解決方法。替換一個命令我沒有在超時分支上使用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

0

有同樣的問題,並記住我首先在MS-DOS 3.30使用的特技,後來在Cygwin的(未超時,但更命令是對於大量的重定向問題)神奇的子彈:

timeout -t 8 getevent | more > getevent.txt 

作品以及在Total Commander的外殼 與SU(未SH)

不客氣:-)