Self-timer Tutorial 52 Python_adb Run Shell Script

Keywords: Python shell Linux Android

Android, as a Linux terminal, must have run Shell scripts that support the.sh suffix.
Sometimes the test environment prepares or intercepts complex logs for a long time, and so on, the development will give you some Shell scripts.
Benefits of Shell script execution:

  1. Quick and efficient, Shell scripts are supported on Linux terminals.
  2. Since the execution and test results are stored inside the Linux terminal, there will be no excessive I/O CPU consumption on the Android system due to repeated input and output from USB and Windows computers.

How do I run Shell scripts from Python?
There's a lot of learning about how to run Shell scripts in Python at the high end.
In the following case, we wrote a top.sh script to continuously intercept the cpu usage of each App on the system.
Continuous interception of cpu usage data is also a common test method for App performance testing (resource consumption).


Three ways to run Shell scripts
order of the day Specific effects
adb shell sh top.sh (low end) Execution runs in the foreground, i.e.'blocking', which makes you wait at this interface.
Shell script automatically stops execution after unplugging the USB cable
ADB shell sh top.sh & (middle) Execution is in the background, i.e.'No blocking', so it's done in the background, and you don't need to wait for it to finish.
Shell script automatically stops execution after unplugging the USB cable
ADB shell nohup sh top.sh & (high end) Execute independently in the background. After execution, the Shell script will run in the background even if you unplug the USB cable.

This case is implemented in a third high-end way



Shell scripts and Python files exist in two ways
Fusion mode Specific effects
Exposed (low end) The top.sh script and Python script are separate files, with top.sh exposed
---run_top_sh.py
---top.sh
Hidden (high end) Hide top.sh as text in Python code
---run_top_sh.py

The explicit method must be ADB push top.sh/sdcard/top.sh.
This case script is implemented in a second high-end, hidden way, how exactly?



Preparatory phase

Step 1: Store the Shell script as a string variable in the Python code block
Step 2: Write the Shell script to a temporary file (note that the Shell script needs to run on Linux and that the line Ender on Linux is \n)
Step 3: Push the above temporary file adb push to/sdcard/cpu.sh
Step 4: Use ADB Shell nohup sh/sdcard/cpu.sh &for long intercept, even if the USB is dropped accidentally, it will not affect the Shell script to continue to intercept top after execution.

Python Batch Script Form

Remember the essence of batch scripting: executing statements in batch order

# coding=utf-8

import os
import tempfile

# copy the Shell script from top.sh as a string variable
top_sh = '''#!/bin/sh
    while true
    do
        top -n 1 >> /sdcard/top.log
        echo -e "$(date +%Y-%m-%d_%H:%M:%S)" >> /sdcard/top.log
        sleep 3
    done
    '''

print("Generating Shell Temporary files for scripts......")
signal, temp_file = tempfile.mkstemp()  # Create a temporary file
with open(temp_file, 'w+', newline="\n") as hf:  # Convert payments into Shell scripts by clicking here, with emphasis on the newline character'\n'
    for line in top_sh:
        hf.write(line)

os.system("adb root") #Necessary root
os.system("adb remount")
os.system("adb wait-for-device")
os.system("adb push %s /sdcard/top.sh" % temp_file)  # Push top.sh script to terminal device
os.system("adb shell chmod 777 /sdcard/top.sh")  # Assignment 777
os.popen("adb shell nohup sh /sdcard/top.sh &")  # Independent background interference-free execution, popen not blocking
print("/sdcard/top.sh Script running undisturbed in the background......")

print("Clear Temporary Files......")
os.close(signal)  # Temporary File Cleanup
os.remove(temp_file)  # Temporary File Cleanup

os.system("pause")

Python Procedural Oriented Function Form

Procedural function-oriented programming thinking should be as follows:
How many functions do you need to do this?
It is best to encapsulate functions as well as possible, exposing only certain parameter interfaces.

import os
import tempfile

# copy the Shell script from top.sh as a string variable
top_sh = '''#!/bin/sh
    while true
    do
        top -n 1 >> /sdcard/top.log
        echo -e "$(date +%Y-%m-%d_%H:%M:%S)" >> /sdcard/top.log
        sleep 3
    done
    '''


def generate_shell(shell_script):
    print("Generating Shell Temporary files for scripts......")
    signal, temp_file = tempfile.mkstemp()  # Create a temporary file
    with open(temp_file, 'w+', newline="\n") as hf:  # Convert payments into Shell scripts by clicking here, with emphasis on the newline character'\n'
        for line in shell_script:
            hf.write(line)
    return signal, temp_file


def clear_tempfile(signal, temp_file):
    print("Clear Temporary Files......")
    os.close(signal)
    os.remove(temp_file)


def push_run_shell(sh_file, push_path):
    os.system("adb root") #Necessary root
    os.system("adb remount")
    os.system("adb wait-for-device")
    os.system("adb push %s %s" % (sh_file, push_path))  # Push top.sh script to terminal device
    os.system("adb shell chmod 777 %s" % push_path)  # Assignment 777
    os.popen("adb shell nohup sh %s &" % push_path)  # Independent background interference-free execution, popen not blocking
    print("%s Script running undisturbed in the background......"%push_path)


signal, temp_file = generate_shell(top_sh)
push_run_shell(temp_file, "/sdcard/top.sh")
clear_tempfile(signal, temp_file)

os.system("pause")

Python Object-Oriented Class Form

The programming thinking of object-oriented classes should be as follows:
If you are given a blank world, what kind of things do you need in this world?
What are the common attributes and methods of these kinds of things?
These kinds (classes) of things (objects), and other kinds (other classes) of things (other objects).
Encapsulate these classes as well as possible, exposing only the external attributes (variables) and methods (functions).

# coding=utf-8

import os
import tempfile

# copy the Shell script from top.sh as a string variable
top_sh = '''#!/bin/sh
    while true
    do
        top -n 1 >> /sdcard/top.log
        echo -e "$(date +%Y-%m-%d_%H:%M:%S)" >> /sdcard/top.log
        sleep 3
    done
    '''


class ShellGeneratorAndRuner():
    '''Generate shell and push into android and run it'''

    def __init__(self, shell_script, push_path):
        self.script_text = shell_script
        self.push_path = push_path
        self.signal = None
        self.temp_file = None

    def generate_shell(self):
        print("In production Shell Temporary files for scripts......")
        self.signal, self.temp_file = tempfile.mkstemp()
        with open(self.temp_file, 'w+', newline="\n") as hf:  # Convert payments into Shell scripts by clicking here, with emphasis on the newline character'\n'
            for line in self.temp_file:
                hf.write(line)

    def push_run_shell(self):
        os.system("adb root")   #Necessary root
        os.system("adb remount")
        os.system("adb wait-for-device")
        os.system("adb push %s %s" % (self.temp_file, self.push_path))  # Push top.sh script to terminal device
        os.system("adb shell chmod 777 %s" % self.push_path)  # Assignment 777
        os.popen("adb shell nohup sh %s &" % self.push_path)  # Independent background interference-free execution, popen not blocking
        print("%s Script running undisturbed in the background......"%self.push_path)


    def clear_tempfile(self):
        os.close(self.signal)
        os.remove(self.temp_file)


if __name__ == '__main__':
    s_obj = ShellGeneratorAndRuner(top_sh, "/sdcard/top.sh")
    s_obj.generate_shell()
    s_obj.push_run_shell()
    s_obj.clear_tempfile()

    os.system("pause")

Operation mode and effect

Make sure your Android device is connected to your computer via a USB cable and your adb device is connected effectively.
All three implementations of the above code can be run directly, such as saving it as run_top_sh.py and placing it on the desktop.
It is recommended that python run_top_sh.py run, or double-click run.
The results are as follows:
Where C:Users\ADMINI~1\AppData\LocalTemp\tmp5way7qgx is the temporary file generated,
Because the above temporary files are not involved by the average user, Shell scripts can be generated "senselessly".


Why encourage hiding Shell scripts into code?
Because, for example, you subsequently wrote a Python tool that was compiled with py2exe.
py2exe can only compile packaged.py files into.Exe, any other non-.py files cannot be packaged into it.
If you publish it to someone else, it's an.exe.
You think your tools are doing better and integrated better.
Conversely, if your.exe tool comes with a bunch of Shell scripts, other resource files, configuration files, and so on,
It is relatively less easy to use, for example, if the supporting files cannot be found.
Or it can be tampered with arbitrarily by the user, causing the program to not function properly, and it can't show the power of your work.


Not just Shell scripts, files in any text form (configuration files, script files, other log files, etc.)
Consider using the above method to accompany.


For more and better original articles, visit the official website: www.zipython.com
Self-timer tutorial (Python tutorial for automated testing, compiled by Wu San)
Original Link: https://www.zipython.com/#/detail?id=97cbb5fd8dcf4c40a549e565ca0b6f6a
You can also pay attention to the subscription number of "Wusanren" WeChat and accept the article push at any time.

Posted by timvw on Sat, 04 Apr 2020 09:51:50 -0700