• ADB原理(第四篇:聊聊adb shell ps与adb shell ps有无双引号的区别)


    前言

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

    adb shell ps -ef

    或者 

    adb shell "ps -ef"

    两种方式都可以使用,你喜欢用哪个呢?但是你知道双引号的作用吗?

    双引号的作用

        从bash解释器的角度看:解释的力度不同,双引号内的有些特殊字符不再处理了

    1、添加双引号的部分,单词分隔功能会失效(空白字符分隔:包括换行、空格、制表符)

    由于单词分隔功能失效,"ps -ef" ,就是一个整体

    2、双引号内仅支持命令替换、变量名替换、还有数字计算、还有转义字符,四种特殊字符

    "$()"、"${}"、"$[]"、比如\n

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


    1、3个参数

    adb shell ps -ef,这个时候adb接受到3个参数,分别是shell、ps、-ef,bash解释器通过空白字符,分隔单词,所以是3个参数

    2、2个参数

    adb shell "ps -ef",此时接受到的是2个参数,由于双引号,让单词分隔功能失效,所以只有shell、以及"ps -ef" ,着2个参数传递给adb命令了

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

    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"

    由于""具备单词分隔功能失效,以及仅只是4种特殊字符(上面提到过的),其他字符不再解释,这里的重定向符号>,bash解释器并不会再去解释

    对于adb命令,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" 

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

    adb shell ps -ef | grep camera

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

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

    adb shell "ps -ef | grep camera"

    ""命令已经让"ps -ef | grep camera"成为一个整体,同时管道符号也不会再解释器,对于adb,它只收到了2个参数,分别是shell、"ps -ef | grep camera",当传入到手机中,调用的是手机上的grep命令

    总结

    1、熟悉双引号""作用,才能理解上面的情况,再强调一遍,双引号会让单词分隔功能失效(空白字符无效),仅支持命令替换、变量名替换、整数计算、转义字符,其他字符,bash解释器都不会再解释,比如 重定向 >,还有 管道 |

    2、重定向、管道符都是bash解释器来处理的,对于命令本身,他们都不知道这些的存在,他们只会向标准输出写入、标准错误写入、至于重定向到文件、还是通过管道进入到其他命令的标准输入,他们都是一概不知道的

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

  • 相关阅读:
    如何在Java中进行单元测试?
    技术分享活动
    2、HTML常用标签
    JSON.toJSONString首字母大小写问题
    Android原生插件开发-包名篇
    React之setState
    题目 1055: 二级C语言-进制转换
    Redis替代Session实现用户短信登录(超级消息解释)
    驱动开发:内核测试模式过DSE签名
    【Flink集群RPC通讯机制(三)】AkkaRpcActor设计与实现:接收RPC消息以及处理逻辑
  • 原文地址:https://blog.csdn.net/cadi2011/article/details/128668611