ADB原理(第四篇:深入理解adb命令有无双引号的区别)

本文探讨了adb命令中使用双引号对参数处理的影响,包括单词分隔的失效、特殊字符的处理以及重定向和管道符在bash解释器中的作用。理解这些有助于避免命令行中的常见问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

    对于经常使用adb的同学,不可避免的一定会这样用adb,比如我们想在手机里执行ps命令,于是在命令行中写下如下代码:

adb shell ps -ef

或者 

adb shell "ps -ef"

两种方式都可以,你喜欢用哪个呢?你知道二者有什么区别吗?????

shell中双引号的2个作用

    要想知道adb shell ps -ef 与 adb shell "ps -ef"的区别,得先知道双引号""在shell脚本中的作用,双引号的2个重要作用:

1、单词分隔功能失效(空白字符:换行、空格、制表符)

shell默认使用空白字符对单词分隔,此时由于单词分隔功能失效,所以"ps -ef" ,成为一个整体,从参数的角度看,算作1个参数(如果没有双引号,就算2个参数)

2、仍对4种特殊字符解释,其他特殊字符不解释

这四个特殊字符是:命令替换、变量名替换、数字计算、转义字符

命令替换:"$()"

变量名替换:"${}"

整数计算:"$[]"

转义字符:\n

adb命令的角度看:adb收到的参数数量不同

    上面已经交代了shell中双引号的作用,这说明adb shell ps -ef和adb shell "ps -ef",参数数量的是不同的

adb命令收到3个参数,分别是shell、ps、-ef,bash解释器通过空白字符,分隔单词,所以是3个参数

adb shell ps -ef

adb命令收到2个参数,由于双引号已经让单词分隔功能失效,所以shell、以及"ps -ef" ,这2个参数传递给adb命令

adb shell "ps -ef"

有重定向时,有无双引号的差别

无双引号

adb shell ps -ef > ./hello.txt

有双引号

adb shell "ps -ef > /sdcard/hello.txt"

他们之间有什么区别呢?我们继续往下看

命令重定向时,命令并不知情重定向的事情

   ps命令根本不知道自己的标准输出写到文件中了,它只是认为仍然写入到标准输出中,至于重定向,都是bash解释器作的事情

最大的区别,文件位置的不同

 1、重定向到本地主机的文件中

adb shell ps -ef > ./hello.txt

    对于adb命令,它只收到3个参数,shell、ps、-ef,至于后面的 > ./hello.txt,不会作为参数传递给命令,而是本地主机的bash解释器自行处理进行重新向的,所以会在本地主机中,而不是手机中,创建一个hello.txt文件,用于插入adb命令返回的标准输出

2、重定向手机文件中

adb shell "ps -ef > /sdcard/hello.txt"

    对于adb命令,此时收到2个参数,shell、以及"ps -ef > /sdcard/hello.txt",所以ps命令的标准输出其实是写入到手机的/sdcard/hello.txt文件中,这是由Android上的bash解释器处理的,所以它自然会写入到手机的文件中

管道符,也有不同

无双引号

adb shell ps -ef | grep camera

 有双引号

adb shell "ps -ef | grep camera" 

最大的区别,执行的是主机的命令、还是手机上的命令,以grep为例

1、执行的是本地主机的grep

adb shell ps -ef | grep camera

    bash解释器看到管道符,代表adb命令以及后面的参数就到管道符那里,所以adb收到了3个参数,分别是shell、ps、-ef。 而 | grep camera,则是由bash解释器继续处理,调用本地主机的grep命令,使用grep的标准输入来接收前一个adb命令的标准输出

2、执行的是手机上的grep命令

adb shell "ps -ef | grep camera"

    ""命令已经让"ps -ef | grep camera"成为一个整体,对于adb,它只收到了2个参数,分别是shell、"ps -ef | grep camera",当传入到手机中,调用的是手机上的grep命令

总结

1、空白字符包括换行符、制表符、空格符

2、shell编程中双引号""的作用要牢记,双引号会让单词分隔功能失效(使用空白字符分隔),再双引号的内部仅支持命令替换、变量名替换、整数计算、转义字符这四种特殊字符的解释,其他字符,bash解释器不再解释,比如 重定向 >,还有管道 |都不会被解释

3、重定向、管道符是bash解释器处理的,对于命令本身,他们只向标准输出写入、标准错误写入、重定向到文件、或者通过管道进入到其他命令的标准输入,命令本身是不知道的

4、理解不同点后,可以避免编写adb命令的一些坑,尤其是使用windows命令行的时候,毕竟windows默认终端上没有grep命令

<think>我们正在处理一个关于使用ADB命令Android设备上查看进程信息的问题。用户特别询问了如何使用`adb ps -ef | grep`来查看进程号。但是,请注意,标准的ADB命令中并没有`adb ps -ef`这样的命令。通常,我们使用`adb shell`进入设备的shell环境,然后在shell中执行Linux命令,或者直接使用`adb shell <command>`来执行单个命令。 根据用户提供的引用,我们可以得知: - 引用[1]和[4]提到了使用`ps`命令查看进程,并通过`grep`过滤出想要的进程,然后使用`awk`提取进程ID(PID)。 - 引用[3]展示了直接使用`adb shell ps | grep <package_name>`来查看特定进程。 因此,正确的做法是使用`adb shell`加上`ps`命令,然后通过管道`grep`过滤出想要的进程。 但是,用户提到的`ps -ef`是Linux系统中常用的命令选项,用于显示所有进程的完整信息。在Android设备上,`ps`命令通常支持一些选项,但可能不支持所有Linux的选项。不过,Android的`ps`命令通常支持`-A`或`-ef`来显示所有进程(具体取决于Android版本和实现)。 因此,我们可以这样写命令: ```bash adb shell ps -ef | grep <关键词> ``` 或者,为了避免因`ps`选项不同而导致的问题,也可以使用: ```bash adb shell ps | grep <关键词> ``` 但是,`ps`命令默认可能只显示当前用户的部分进程,所以使用`ps -A`或`ps -ef`(如果支持)可以显示所有进程。 另外,引用[1]中给出了一个例子: ```bash ps aux | grep mysql | grep -v grep | awk '{print $2}' ``` 这里使用了`aux`选项,同样是为了显示所有进程,并且通过`grep -v grep`来排除掉grep进程本身,然后使用`awk`提取第二列(即PID)。 在Android环境下,我们也可以采用类似的方法。 所以,针对用户的问题,我们可以给出以下步骤: 1. 使用`adb shell`进入设备的shell,然后执行`ps -ef | grep <包名或进程名>`,或者直接使用: ```bash adb shell "ps -ef | grep <关键词>" ``` 注意:如果直接在命令行中使用管道,在Windows命令提示符中可能需要使用引号将整个命令括起来,而在Linux或Mac的终端中则不需要。 2. 为了避免grep进程自身也被显示出来,可以加上`grep -v grep`来排除: ```bash adb shell "ps -ef | grep <关键词> | grep -v grep" ``` 3. 如果只需要进程号,可以使用`awk`(在Android中,通常有`awk`工具,但如果没有,可以使用`cut`或者`busybox awk`等)提取PID: ```bash adb shell "ps -ef | grep <关键词> | grep -v grep | awk '{print \$2}'" ``` 注意:在双引号内使用`$`需要转义,所以写成`\$2`。 但是,需要注意的是,不同Android设备上的`ps`命令输出格式可能不同。常见的格式有两种: - UNIX风格:列包括USER, PID, PPID, VSIZE, RSS, WCHAN, PC, NAME等(使用`ps`命令)。 - 另一种格式(使用`ps -ef`):列包括UID, PID, PPID, C, STIME, TTY, TIME, CMD。 所以,使用`ps -ef`时,PID在第二列,而使用`ps`(不带选项)时,PID可能在第二列(但列名可能不同,且列数可能更多)。因此,为了确保正确获取PID,最好先查看一下`ps`命令的输出格式,再决定提取哪一列。 另外,引用[3]中直接使用了`adb shell ps | grep com.tencent.mm`,输出中第二列就是PID。 因此,我们可以建议用户先尝试: ```bash adb shell ps | grep <包名> ``` 或者 ```bash adb shell ps -ef | grep <包名> ``` 然后观察输出,确定PID在第几列。 最后,给出一个通用的命令来获取进程ID(假设使用`ps -ef`,PID在第二列): ```bash adb shell "ps -ef | grep <包名> | grep -v grep | awk '{print \$2}'" ``` 如果设备不支持`ps -ef`,可以使用`ps`(不带选项)并调整列号(可能是第二列): ```bash adb shell "ps | grep <包名> | grep -v grep | awk '{print \$2}'" ``` 另外,引用[4]提到了一种更简单的方法:使用`adb shell pidof <包名>`。但是,`pidof`命令Android设备上不一定可用。如果可用,那将是最简单的方式: ```bash adb shell pidof <包名> ``` 所以,我们也可以建议用户尝试使用`pidof`(如果设备支持)。 综上所述,我们给出以下回答:</think>### 使用ADB查看Android进程号的方法 在Android设备上查看特定进程的进程号(PID),正确的ADB命令组合如下: ```bash adb shell "ps -ef | grep 关键词" ``` #### 具体操作步骤: 1. **连接设备**:确保设备已通过USB调试连接 2. **执行命令**(示例查看微信进程): ```bash # 查看微信相关进程 adb shell "ps -ef | grep com.tencent.mm" # 输出示例: u0_a119 4954 484 1806396 145448 SyS_epoll_ 00e8f3e428 S com.tencent.mm u0_a119 5057 484 1544788 103900 SyS_epoll_ 00e8f3e428 S com.tencent.mm:push ``` 输出中**第二列即为进程号**(如上例中的4954和5057)[^3][^4]。 #### 命令说明: - `adb shell`:进入Android设备的Linux shell环境 - `ps -ef`:列出所有正在运行的进程(Android兼容POSIX标准) - `grep 关键词`:过滤包含特定关键词的进程(通常用应用包名,如`com.tencent.mm`) - 管道符 `|`:将`ps`的输出传递给`grep`进行过滤 #### 进阶用法: 1. **精确提取PID**: ```bash adb shell "ps -ef | grep 关键词 | grep -v grep | awk '{print \$2}'" ``` 这会直接输出纯数字PID(如`4954`)[^1] 2. **查看特定包名的进程**: ```bash adb shell pidof <包名> # 示例:adb shell pidof com.tencent.mm ``` (需设备支持`pidof`命令) #### 注意事项: 1. 部分Android定制系统可能精简了`ps`参数,若`-ef`失效可改用: ```bash adb shell ps | grep 关键词 ``` 2. Windows命令行需使用双引号包裹整个命令,避免管道符解析错误 3. 确保USB调试模式已开启(开发者选项内) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值