慕雪的小助手正在绞尽脑汁···
慕雪小助手的总结
DeepSeek & LongCat

用 adb 起跳链测试,链接带 & 参数时命令被截断——记录一下正确写法。

1.起因

最近在做 deeplink 跳转的测试,需要用 adb 直接拉起一个带参数的跳链,类似这样:

1
adb shell am start -d "myapp://home?from=test&tab=2" -a android.intent.action.VIEW

结果 App 收到的参数不对,一看日志,发现 tab=2 整个都没有传进去,跳链在 & 那里就断了。

然后我想着,这是 shell 特殊字符的问题,加个单引号把跳链包起来不就完了:

1
adb shell am start -d 'myapp://home?from=test&tab=2' -a android.intent.action.VIEW

还是不行,照样截断。

2.原因

这里有两层 shell 在处理命令:

  1. 本机的 shell(你的终端,zsh/bash)
  2. 设备上的 shell(adb 连进去之后的 Android shell)

adb shell 后面跟的命令,会先经过本机 shell 解析一遍,再传给设备 shell 执行。& 在 shell 里是后台运行的特殊符号,本机 shell 一看到它就直接把命令切断了,压根轮不到设备那边去处理。

只把跳链用单引号包起来,保护的只是跳链这个字符串,而 adb shell 本身的参数传递还是经过了本机 shell 的解析,所以没用。

3.解决

有两种方式可以解决这个问题。

方式一:单引号包住整个命令,跳链改用双引号

1
2
3
4
5
# 错误写法 —— 只包了跳链,& 仍然被本机 shell 截断
adb shell am start -d 'myapp://home?from=test&tab=2' -a android.intent.action.VIEW

# 正确写法 —— 单引号包住整个命令,跳链用双引号
adb shell 'am start -d "myapp://home?from=test&tab=2" -a android.intent.action.VIEW'

这样本机 shell 看到外层的单引号,会把里面的内容原封不动地整体传给 adb shell& 就不会被截断了。设备上的 shell 收到完整命令之后,再去解析里面的双引号和参数,一切正常。

方式二:echo 管道传给 adb shell

1
echo 'am start -d "myapp://home?from=test&tab=2" -a android.intent.action.VIEW' | adb shell

echo 把命令字符串原样输出,通过管道 | 直接送进 adb shell 的标准输入执行,本机 shell 只负责跑 echo,不会再去解析后面的内容,& 自然也就安全了。

两种方式效果一样,方式二在命令特别长的时候可读性稍好一点,随喜好选用。

The end

这个坑比较隐蔽,因为报错不明显——App 不会崩,只是参数悄悄丢了,定位起来挺费劲的。以后只要跳链里带 &,直接按正确写法来就行了。

有问题欢迎评论区交流!