2017-06-19 205 views
2

從shell腳本循環運行多個adb命令時,我注意到一個問題,大多數命令都沒有執行。爲什麼ADB命令打破了bash腳本循環?

這是一個示例腳本。

腳本名稱:adbscript.sh

#!/bin/bash 

devicecount=0 
while read device; do 
    ((devicecount++)) 
    serialno="NA" 
    appinstallcount="NA" 
    echo "Processing Device #$devicecount: $device" 
    # serialno=$(adb -s $device shell getprop ro.serialno) 
    # appinstallcount=$(adb -s $device shell pm list packages | wc -l) 
    echo -e "Device: $device | Serialno: $serialno | Apps installed: $appinstallcount\n" 
done < <(adb devices | egrep "\bdevice\b" | awk '{print $1}') 
echo "Finished." 

輸出與亞行命令註釋

我具有連接5個裝置。當從bash文件運行而沒有adb命令時,這是輸出。它遍歷5個循環的每一個。

 
Processing Device #1: 192.168.15.93:5123 
Device: 192.168.15.93:5123 | Serialno: NA | Apps installed: NA 

Processing Device #2: 192.168.15.95:5123 
Device: 192.168.15.95:5123 | Serialno: NA | Apps installed: NA 

Processing Device #3: emulator-5554 
Device: emulator-5554 | Serialno: NA | Apps installed: NA 

Processing Device #4: 31005c77c8cfb200 
Device: 31005c77c8cfb200 | Serialno: NA | Apps installed: NA 

Processing Device #5: 98883837594d4f5453 
Device: 98883837594d4f5453 | Serialno: NA | Apps installed: NA 

Finished. 

輸出與含有ADB命令

adb shell命令是所述第一循環的未註釋它只正確迭代線迴路。這與adb命令的輸出未註釋:

 
Processing Device #1: 192.168.15.93:5123 
Device: 192.168.15.93:5123 | Serialno: 98883837594d4f5453 | Apps installed: 442 

Finished. 

有人能解釋這種行爲,將有什麼工作要做,以具有所有的線路和所有的循環處理?

順便說一句,這是提供給腳本(一個襯裏命令和輸出)的輸出:

$ adb devices | egrep "\bdevice\b" | awk '{print $1}' 
192.168.15.93:5123 
192.168.15.95:5123 
emulator-5554 
31005c77c8cfb200 
98883837594d4f5453 
+1

最佳猜測 - 'adb'命令正在使用stdin。嘗試在'adb'命令中重定向stdin'

+0

謝謝!有用。如果你以答案的形式提出你的決議,我會接受答案,並提高貢獻。 –

回答

5

adb shell連接標準輸入到該設備上運行的命令,這通常會消耗標準輸入,直到EOF到達了。所以這些命令會消耗所有其餘的設備名稱,導致循環退出。

與標準輸入重定向運行adb,使他們獲得立即EOF不與你在試圖環路什麼搞亂:

serialno=$(adb </dev/null -s $device shell getprop ro.serialno) 
appinstallcount=$(adb </dev/null -s $device shell pm list packages | wc -l) 
+0

你也可以使用'adb shell -n <你的命令>'來防止從標準輸入中讀取 – ldanko

1

雖然@ ChrisDodd的根本原因分析是正確的,他的解決方案,工作正常一般來說,對於adb自動化目的,對於簡單的adb shell命令,最好使用adb exec-out而不是建議的adb </dev/null shell

此外,爲什麼在使用awk時使用grep

for device in $(adb devices | awk '$2=="device"{print$1}') 
do 
    serialno=$(adb -s $device exec-out getprop ro.serialno) 
    appinstallcount=$(adb -s $device exec-out pm list packages | wc -l) 
    ... 
done 

對於adb exec-out工作,你需要兩個PC主機和設備有幾分最近adb(或adbd中的設備的情況下)版本 - platform-tools V24 +和Android 5.1+應該做的。

+0

我使用'adb'完成許多與我的設備通信的任務。我使用我的電腦,大鍵盤和多個屏幕花了99%的設備/電腦時間。所以** adb **命令的許多功能都很有價值。很長時間以來,我一直被這個難題所困擾(這對我來說是一個限制)。我已將'adb失敗。 –

+0

謝謝!在這種情況下,我使用了** grep **,同時快速從我的一個工具中抽取一個示例塊,這些工具可以很容易地進行測試,以顯示我的問題以及我正在尋找的內容。我花了一點時間來微調它。我刪除了很多冗餘,但是我看到,我仍然可以刪除更多。發佈後,我發現可以執行一些清理,包括您指出的冗餘。我沒有看到一些表達方式對實際問題和解決方案有很大影響。 –

+0

儘管您的回答並未解決問題的**輸入/重定向問題**,但您提供的腳本示例解釋了執行輸出的優點。再次感謝貢獻。我鼓勵你的答案在bash腳本中使用adb有好處。但如果它解決了這個問題的錯誤,我錯過了一些東西。 –