【问题标题】:Shell Script Running adb commands break the while loop [duplicate]运行 adb 命令的 Shell 脚本会中断 while 循环 [重复]
【发布时间】:2018-11-21 06:01:46
【问题描述】:

我正在编写一个 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

【问题讨论】:

    标签: android bash shell adb


    【解决方案1】:

    我在这里猜测,但可能是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 通常未使用)。使用这种形式,您不必知道循环内的哪些命令可能从标准输入中读取,因此不足为奇(如果它们确实需要从终端读取,它们可以!)。此外,与标准管道不同,它在主 shell 进程而不是子 shell 中运行循环,从而避免了一些奇怪的事情(比如循环中设置的变量在循环之后不可用)。

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

    【讨论】:

    • 第一个建议仍然会中断 while 循环,但您最喜欢的解决方案有效!谢谢!
    猜你喜欢
    • 2014-11-03
    • 1970-01-01
    • 2012-01-06
    • 2015-04-02
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多