【问题标题】:Command giving no output when being read?读取命令时没有输出?
【发布时间】:2013-02-20 22:31:42
【问题描述】:

我有一个很奇怪的问题。我不知道为什么会发生这种情况或如何解决它。

脚本:

#!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 "$*"
    "$@" | 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 循环的第一行甚至没有运行。

使用 set -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 上有任何解决方法。

【问题讨论】:

  • 离题了。试试 XDA 开发人员
  • @Simon 这怎么跑题了?考虑到我遇到的问题,它可能会使用 android 特定的命令,但这是一个编程问题。
  • 对不起,我对这个特殊的 shell 奥秘无能为力,但 +1 表示精心设计的问题,显示了相当多的工作。继续发帖。祝你好运!
  • @shellter ormaaj 重写了我的第一个脚本(后来我不得不修改他的版本,因为我的 shell 明显有问题),所以脚本的功劳应该给他 :)

标签: android bash shell sh busybox


【解决方案1】:

我认为没有办法在busybox的grep中启用line-buffering,但你可以这样做:

$ adb shell timeout -t 10 getevent -t | \
    grep --line-buffered -v -E "add device|name:" | \
    while read line; do echo "READ: $line"; done

【讨论】:

  • 即使没有 --line-buffered 使用 adb (和 Ubuntu)也可以工作,但是当我在没有 --line-buffered 的情况下使用 Android 的 shell 尝试它时会出现同样的问题(如你所说,它不受支持) .
  • 如果您尝试保存事件列表以便稍后重现,使用主机可能是更好的解决方案。
  • 整个想法是在设备本身上使用它(例如直接与其他应用程序一起使用,例如:LMT Launcher、Tasker 等),并与可能未运行的观众分享Linux 发行版(或准备使用 Cygwin)。
【解决方案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 "$*"
    "$@" <&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 "$@" 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

【讨论】:

  • Assignments 出现错误:eval: arith: syntax error: "t2=t1" eval: arith: syntax error: "(t = (t1 = 45534) -t2) &gt; 0 &amp;&amp; t2 &gt; -1" 话虽如此,转换实际上适用于cat,但是当我替换 @ 时,同样的问题被重现(根本不输出 - 甚至没有错误) 987654326@geteventgetevent -t
【解决方案3】:

遇到了同样的问题,并记得我第一次在 MS-DOS 3.30 中使用的技巧,后来在 Cygwin 中使用(不是用于超时,但 more 命令是解决许多重定向问题的神奇子弹):

timeout -t 8 getevent | more > getevent.txt

在 Total Commander 的 shell 中运行良好 用 su(不是 sh)

不客气 :-)

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 2011-10-17
    • 2017-12-15
    相关资源
    最近更新 更多