ADB多设备自动化脚本故障:IP与邮箱无法一一匹配
问题背景
我正在实现多台设备/机顶盒的自动化定制流程,以下Bash脚本可从device_ips.txt读取IP地址,依次连接设备、执行ADB命令、断开后连接下一台设备,该部分功能正常。
#!/bin/bash while true; do ip_file="device_ips.txt" if [ ! -f "$ip_file" ]; then echo "Error: $ip_file not found." exit 1 fi # Read the IP addresses from the file into an array mapfile -t device_ips < "$ip_file" for device_ip in "${device_ips[@]}"; do device_ip=$(echo "$device_ip" | tr -d '\r') # Remove any Windows-style carriage return characters if [ -z "$device_ip" ]; then echo "Error: No IP address found in the file." exit 1 fi adb disconnect adb connect "$device_ip" connected=$(adb devices | grep "$device_ip" | awk '{print $2}') if [ "$connected" != "device" ]; then echo "Error: Connection to $device_ip failed." continue fi # Commands to be executed adb root adb remount adb install... # rest of adb commands... #LOGIN email_file="emails.txt" mapfile -t email < "$email_file" while IFS= read -r email; do email=$(echo "$email" | tr -d '\r') adb shell input tap 886 337 # Taps on empty textbox where email has to typed for ((i=0; i<${#email}; i++)); do adb shell input text "${email:i:1}" # types email done adb shell input tap 930 549 # login done < "$email_file" wait done done
device_ips.txt格式如下:
192.168.0.123 192.168.0.132 192.168.0.146
emails.txt格式如下:
id_1@email.com id_2@email.com id_3@email.com
问题描述
脚本的登录环节(#LOGIN下方代码)存在异常:期望实现每个IP对应一个邮箱(如192.168.0.123对应id_1@email.com,192.168.0.132对应id_2@email.com),但当前所有设备均重复输入第一个邮箱id_1@email.com。我曾尝试将登录循环从while IFS= read -r email; do改为for email in "${email[@]}"; do,结果所有邮箱被连续输入(如id_1@email.comid_2@email.comid_3@email.com)且在所有设备重复。现寻求解决方法,实现IP与邮箱按顺序一一匹配输入。
解决方案
核心思路是提前将IP和邮箱加载到数组中,通过索引循环实现两者的一一绑定,避免在设备循环内重复读取文件或遍历所有邮箱。修改后的完整脚本如下:
#!/bin/bash while true; do ip_file="device_ips.txt" email_file="emails.txt" # 检查必要文件是否存在 if [ ! -f "$ip_file" ]; then echo "Error: $ip_file not found." exit 1 fi if [ ! -f "$email_file" ]; then echo "Error: $email_file not found." exit 1 fi # 提前加载IP和邮箱到数组(仅执行一次) mapfile -t device_ips < "$ip_file" mapfile -t emails < "$email_file" # 检查IP与邮箱数量是否匹配 if [ ${#device_ips[@]} -ne ${#emails[@]} ]; then echo "Warning: IP数量(${#device_ips[@]})与邮箱数量(${#emails[@]})不匹配,将跳过多余的设备/邮箱" fi # 使用索引循环,实现IP与邮箱一一对应 for ((i=0; i<${#device_ips[@]}; i++)); do device_ip=$(echo "${device_ips[i]}" | tr -d '\r') # 若当前索引无对应邮箱,跳过该设备 if [ $i -ge ${#emails[@]} ]; then echo "Warning: 设备 $device_ip 无对应邮箱,跳过" continue fi email=$(echo "${emails[i]}" | tr -d '\r') # 跳过空的IP或邮箱 if [ -z "$device_ip" ] || [ -z "$email" ]; then echo "Error: 空的IP或邮箱,跳过当前设备" continue fi adb disconnect adb connect "$device_ip" # 验证设备连接状态 connected=$(adb devices | grep "$device_ip" | awk '{print $2}') if [ "$connected" != "device" ]; then echo "Error: 连接 $device_ip 失败,跳过" continue fi # 执行ADB初始化命令 adb root adb remount # adb install... 保留你的其他ADB命令 # 登录操作:使用当前设备对应的单个邮箱 adb shell input tap 886 337 # 点击邮箱输入框 # 逐字符输入邮箱(避免特殊字符解析问题) for ((j=0; j<${#email}; j++)); do adb shell input text "${email:j:1}" done adb shell input tap 930 549 # 点击登录按钮 wait done done
关键修改说明
- 提前加载数组:将IP和邮箱的读取操作移到设备循环外,确保只读取一次文件,同时保证两个数组的索引对应关系。
- 索引循环替代遍历:使用
for ((i=0; i<${#device_ips[@]}; i++))循环,通过索引i同时获取对应的IP和邮箱,实现一一绑定。 - 增加边界检查:处理IP与邮箱数量不一致的情况,避免数组越界或无对应数据的问题。
- 移除冗余循环:删除原登录环节的邮箱遍历循环,直接对当前设备对应的单个邮箱执行输入操作。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

