Python调用Shell

一:adb 调试命令

os.system(cmd)的返回值是脚本的退出状态码,只会有0(成功),1,2,返回一个信号代码
os.popen(cmd)返回脚本执行的输出内容作为返回值

二:os.system(cmd)

1,介绍

os.system方法是os模块最基础的方法,其它的方法一般在该方法基础上封装完成。

详解

os.system()的返回值是脚本的退出状态码,0表示成功,其他均为失败:

import os
a = os.system('adb shell ls -lh /sdcard/tmp/screenshot/')
print(a)
=============================
成功:
-rw-rw---- 1 root sdcard_rw 14 2021-12-20 23:23 1.txt
0
=============================
失败:
error: device not found
-1

2, 多条子进程

system函数可以将字符串转化成命令在服务器上运行;其原理是每一条system函数执行时,其会创建一个子进程在系统上执行命令行,
为了使操作的连续性可以用以下(; )连接命令
例如:

import os
a = os.system('adb shell cd /sdcard/tmp/screenshot/;cat 1.txt')
print(a)
=================================
how are you ?
0

三:os.popen(cmd)

1,介绍

os.popen() 方法,可以实现一个“管道”,从这个命令获取的值可以在python 中继续被使用

语法
popen()方法语法格式如下:

os.popen(command[, mode[, bufsize]])
参数
command – 使用的命令。

mode – 模式权限可以是 ‘r’(默认) 或 ‘w’。

bufsize – 指明了文件需要的缓冲大小:0意味着无缓冲;1意味着行缓冲;其它正值表示使用参数大小的缓冲(大概值,以字节为单位)。负的bufsize意味着使用系统的默认值,一般来说,对于tty设备,它是行缓冲;对于其它文件,它是全缓冲。如果没有改参数,使用系统的默认值。

返回值
返回一个文件描述符号为fd的打开的文件对象

2,执行命令

import os
command ='adb shell ls -lh /sdcard/tmp/screenshot/'
a = os.popen(command, 'r' ,1)
print(a)
=============================
<os._wrap_close object at 0x0000018A90002208>

3,获取返回值

三种方式

import os
command ='adb shell ls -lh /sdcard/tmp/screenshot/'
a = os.popen(command, 'r' ,1).read()
print(a)
========================
total 4.0K
-rw-rw---- 1 root sdcard_rw 14 2021-12-20 23:23 1.txt
import os
command ='adb shell ls -lh /sdcard/tmp/screenshot/'
a = os.popen(command, 'r' ,1).readline()
print(a)
===================
total 4.0K
import os
command ='adb shell ls -lh /sdcard/tmp/screenshot/'
a = os.popen(command, 'r' ,1).readlines()
print(a)
================================
['total 4.0K\n', '-rw-rw---- 1 root sdcard_rw 14 2021-12-20 23:23 1.txt\n']

补充:read()/readline()/readlines()区别

方法类型返回文本
read()str以原格式返回全部文本
readline()str只返回第一行文本
readlines()str以原格式返回全部文本
也可以选择读取第几行linecache 模块
file_path = r'C:\Users\Administrator\Desktop\test.txt'
a = linecache.getline(file_path,2)
print(a)
=====================
12232
command ='adb shell ls -lh /sdcard/tmp/screenshot/'
file_path = r'C:\Users\Administrator\Desktop\test.txt'
a = linecache.getlines(file_path,2)
print(a)
==============================
['\n', '12232\n', '\n', 'aaf\n', 'd\n', 'aaf\n', '\n', 'df\n', 'aaf\n', 'dfa\n']

四:subprocess(cmd)

1,介绍

subprocess模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值

2,subprocess.run(cmd)

run 方法语法:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)

args:表示要执行的命令。必须是一个字符串,字符串参数列表。
stdin、stdout 和 stderr:子进程的标准输入、输出和错误。其值可以是 subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者 None。subprocess.PIPE 表示为子进程创建新的管道。subprocess.DEVNULL 表示使用 os.devnull。默认使用的是 None,表示什么都不做。另外,stderr 可以合并到 stdout 里一起输出。
timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。

注意:
run 方法调用方式返回 CompletedProcess 实例,和直接 Popen 差不多,实现是一样的,实际也是调用 Popen,与 Popen 构造函数大致相同

3,run()举例

ret.returncode == 0 代表执行成功

import subprocess
command= "adb shell ls -lh"
ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
if ret.returncode == 0:
    print("success:",ret)
else:
    print("error:",ret)
    ========================
    success: CompletedProcess(args='adb shell ls -lh', returncode=0, stdout='ls: ./version.prop: Permission denied\nls: ./verity_key: Permission denied\nls: ./ueventd.rc: Permission denied\n)
if ret.returncode == 0:
    print("success:",ret.stdout)
else:
    print("error:",ret.stderr)
  =======================
  uccess: ls: ./version.prop: Permission denied
ls: ./verity_key: Permission denied
ls: ./ueventd.rc: Permission denied
ls: ./rootscan.conf: Permission denied
ls: ./resetFactory.cfg: Permission denied

4, Popen() 方法

1,介绍

Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。
构造函数:

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, 
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, 
startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(),
*, encoding=None, errors=None)
常用参数:

args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:缓冲区大小。当创建标准流的管道对象时使用,默认-1。
0:不使用缓冲区
1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
正数:表示缓冲区大小
负数:表示使用系统默认的缓冲区大小。
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
cwd:用于设置子进程的当前目录。
env:用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承。

单行命令执行

command ='ls -lh /sdcard/tmp/screenshot/'
pipe = subprocess.Popen('adb shell '+command,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True)
curline= pipe.stdout.readlines()
if curline !='':
    print(curline)
==============================
[b'total 4.0K\r\n', b'-rw-rw---- 1 root sdcard_rw 14 2021-12-20 23:23 1.txt\r\n']
import subprocess
def cmd(command):
    subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
    subp.wait(2)
    if subp.poll() == 0:
        print(subp.communicate()[1])
    else:
        print("失败")
cmd("java -version") # 相当于 adb shell java -version
===========================
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

import subprocess
cmds = [r’cd /sdcard/data’,r’cat 1.txt’]
pipe = subprocess.Popen(“adb shell “,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
out,err = pipe.communicate((”\n”.join(cmds)+“\n”).encode(“UTF-8”))
print(out,err)


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

45度看我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值