You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键修改说明

  1. 提前加载数组:将IP和邮箱的读取操作移到设备循环外,确保只读取一次文件,同时保证两个数组的索引对应关系。
  2. 索引循环替代遍历:使用for ((i=0; i<${#device_ips[@]}; i++))循环,通过索引i同时获取对应的IP和邮箱,实现一一绑定。
  3. 增加边界检查:处理IP与邮箱数量不一致的情况,避免数组越界或无对应数据的问题。
  4. 移除冗余循环:删除原登录环节的邮箱遍历循环,直接对当前设备对应的单个邮箱执行输入操作。

内容的提问来源于stack exchange,提问作者Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:14:51