Shell脚本运行adb命令打破了while循环

时间:2018-11-21 06:01:47

标签: android bash shell adb

我正在编写一个bin bash shell脚本,以一次从多个设备收集信息。但是我注意到在while循环中是否执行了任何adb命令都会破坏它。不知道为什么,因为循环显然没有完成。我知道有多个提要讨论此主题,但是我找不到类似的问题。任何建议都会有所帮助。谢谢。

#!/bin/bash
echo "# Collecting attached devices under adb and record the project name..."
adb devices | while read line
do

   if  [ "$line" != "" ] && [ `echo $line | awk '{print $2}'` = "device" ]
then

device_sn=`echo $line | awk '{print $1}'`

project_name=`adb -s $device_sn shell getprop ro.product.device` #This line will break the while loop. If I remove it I can have all connected devices reboot to bootloader

echo "$project_name: $device_sn is rebooting to bootloader"

adb -s $device_sn reboot bootloader

   fi
done

1 个答案:

答案 0 :(得分:0)

我在这里猜测,但是可能是adb命令正在读取打算用于while read的输入。 while read类型循环是一个相当普遍的问题,并且您描述的症状匹配。一种可能性是重定向内部命令上的输入,以使它无法从意外的源中读取,如下所示:

project_name=`adb -s $device_sn shell getprop ro.product.device` </dev/null

但是我最喜欢的解决方案是通过更改while read循环,将输入传递到标准输入以外的其他循环上。

while read line <&3
do
    # normal loop contents here...
done 3< <(adb devices)

那些重定向通过文件描述符#3的输入(#0是标准输入,#1是标准输出,#2是标准错误,#3通常未使用)。使用这种形式,您不必知道循环中的哪些命令可能会从标准输入中读取内容,因此不会感到惊讶(而且如果确实需要从终端读取内容,则可以!)。另外,与标准管道不同,它在主外壳程序而不是子外壳程序中运行循环,从而避免了许多奇怪的情况(例如循环中设置的变量在循环后不可用)。

尽管有一个缺点:进程替换<( )是仅bash的功能。当它以sh的名称运行时,甚至在bash中都不可用!因此,您必须在脚本(#!/bin/bash#!/usr/bin/env bash)中使用bash shebang,并且不要通过使用sh运行脚本来覆盖它!