我正在编写一个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
答案 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
运行脚本来覆盖它!