危险命令禁区 - 哪些命令 Runner 执行不了或不该执行
Runner 处理命令的硬限制
Runner 的命令执行有几个硬性限制——这不是 bug,是开发者为了防止 APP 卡死做的安全设计:
| 限制 | 阈值 | 原因 |
|---|---|---|
| 单次输出上限 | 约 1000 字符 | 超过后 Runner 强行关闭输出管道并终止命令,返回值 141(SIGPIPE) |
| 无限输出 | 不支持 | 没有终端控制码,Runner 无法停止正在无限输出的进程 |
| 执行超时 | 部分版本有 | 执行过久的命令可能被 Runner 主动终止 |
禁区一:无限输出命令
这类命令不要在 Runner 里直接跑,它们会永远运行直到手机重启:
# logcat 持续输出
logcat 2&1 > /sdcard/log.txt
# 实时监控系统事件
dumpsys activity activities --watch
# 持续监控网络流量
top -b -d 1
原因:Shizuku Binder 通道不支持终端控制码(如 Ctrl+C),Runner 无法给子进程发送终止信号。一旦这类命令启动,子进程会一直跑,Runner 界面卡死在执行中,直到手机主动杀进程或你重启。
替代方案:把无限输出改成有限时长或有限次数:
# 只捕获 10 秒的 logcat
timeout 10 logcat -d > /sdcard/log.txt
# 只看一次,不持续
dumpsys activity activities
注意:timeout 命令不是所有 Android 版本都支持,如果报 timeout: not found 说明你的系统没这个工具。
禁区二:超大输出命令
这类命令输出量巨大,会被 Runner 截断并返回 141:
# 列出所有进程详情(可能几百行)
dumpsys activity all
# 导出完整的 battery history
dumpsys batterystory
# 列出所有 app 的 package info
dumpsys package
返回值 141 的含义:SIGPIPE(Broken Pipe)——写管道时管道已关闭。Runner 检测到输出超过阈值后主动关闭了读取端,shell 子进程在写入时收到 SIGPIPE 信号就终止了。输出只会被截断,不会全部丢失。
替代方案:重定向到文件再读:
# 直接让 shell 写文件,不走 Runner 的输出通道
dumpsys activity all > /sdcard/activity_dump.txt 2>&1
# 然后用 cat 或 less 看文件
禁区三:阻塞性命令
会一直等待用户输入的命令:
# 交互式编辑器
vi /sdcard/file.txt
# 需要输入 Y/N 的命令
install -r /data/local/tmp/app.apk
Runner 不支持交互式命令——它只会给命令喂空输入(如果有),不会弹出输入框让你在手机上敲。这类命令要么跳过交互直接执行(加 -y 或 --yes 参数),要么用非交互式方式重写。
禁区四:破坏性命令
shell 权限下就够危险、root 权限下会搞崩系统的命令:
# 删光 /system
rm -rf /system/*
# 清空所有应用数据
pm clear --all
# 修改 SELinux 为 permissive(绕过安全)
setenforce 0
# 修改只读系统属性
setprop ro.build.fingerprint "hack"
降权开关能帮你挡掉大部分 shell 权限下做不到的 root 破坏性操作,但不能帮你挡 shell 权限下本身就能做到的危险操作(比如 pm clear --all、pm disable --all)。
安全命令示例
对比之下,这些命令是 Runner 里相对安全、常用的:
# 查询类(输出小、只读)
pm list packages | grep weibo
dumpsys battery
getprop ro.build.display.id
ps -A | grep -v zygote
# 常规操作类(有回滚空间)
pm disable-user --user 0 包名 # 可以 enable 回来
am force-stop 包名 # 只是杀进程,App 还在
screencap -p /sdcard/screen.png