如何让子Shell(Subshell)成为别名(Alias)的一部分并在远程ADB设备上执行?
如何让子Shell(Subshell)成为别名(Alias)的一部分并在远程ADB设备上执行?
这个问题其实很常见——别名的展开逻辑和你预期的不一样,咱们一步步来解决:
为什么你的别名会失败?
别名是由本地Shell先解析所有变量、子shell和特殊符号,再把最终结果传给adb执行的。你写的$(stat -c %u /data/data/com.termux)会被本地Shell优先执行,但你的电脑上根本没有Android设备的/data/data/com.termux目录,自然就会报错。
最优解:用Shell函数代替别名
函数比别名灵活得多,完全能处理这种需要远程执行子shell的场景,写法也更清晰:
ashell() { adb shell "su \$(stat -c %u /data/data/com.termux) -s /data/data/com.termux/files/home/bin/termuxshell" }
这里的关键是把$转义成\$,这样本地Shell不会提前解析$(stat...),而是把这个子shell命令完整传递到远程设备的adb shell环境中执行,远程设备就能正确读取Termux目录的UID了。
使用方法:
- 把这段函数代码添加到你的Shell配置文件里(比如
~/.bashrc、~/.zshrc,取决于你用的是Bash还是Zsh) - 执行
source ~/.bashrc(或对应的配置文件)重新加载配置 - 之后直接输入
ashell就能调用这个命令了
如果你非要用别名的话(不推荐)
也可以实现,但写法更绕,可读性差,以后修改容易出错:
alias ashell='adb shell '\''su $(stat -c %u /data/data/com.termux) -s /data/data/com.termux/files/home/bin/termuxshell'\'
这里用了单引号嵌套的技巧:外层单引号包裹整个adb命令,内层用'\''在单引号中插入单引号,让本地Shell完全不解析里面的$(...),直接把命令传给远程Shell执行。
总结
毫无疑问,函数是更好的选择——它不仅解决了当前的子shell执行问题,还方便后续扩展(比如添加设备选择参数、错误处理逻辑等),维护起来也更简单。
备注:内容来源于stack exchange,提问作者Dr. Coomer
相关产品推荐
相关产品推荐

