Kas ir Python apakšprocess? [5 Usage Examples]

Apakšprocesi ļauj mijiedarboties ar operētājsistēmu pilnīgi jaunā līmenī.

Mūsu dators visu laiku palaiž apakšprocesus. Faktiski, vienkārši izlasot šo rakstu, jūs palaižat daudzus procesus, piemēram, tīkla pārvaldnieku vai pašu interneta pārlūkprogrammu.

Foršā lieta ir tāda, ka jebkura darbība, ko mēs veicam savā datorā, ir saistīta ar apakšprocesa izsaukšanu. Tas joprojām ir taisnība, pat ja mēs rakstām vienkāršu „sveiki pasaule” skriptu python.

Apakšprocesa jēdziens var šķist neskaidrs pat tad, ja kādu laiku esat mācījies programmēt. Šajā rakstā tiks detalizēti apskatīta apakšprocesa galvenā koncepcija un Python izmantošana apakšprocesa standarta bibliotēka.

Līdz šīs apmācības beigām jūs:

  • Izprast apakšprocesa jēdzienu
  • Ir apguvuši Python apakšprocesu bibliotēkas pamatus
  • Praktizējiet savas Python prasmes ar noderīgiem piemēriem

Iedziļināsimies tajā

Apakšprocesa jēdziens

Plaši sakot, apakšprocess ir a datora process radīts cita procesa rezultātā.

Mēs varam domāt par apakšprocesu kā koku, kurā katram vecākajam procesam aiz tā darbojas pakārtotie procesi. Es zinu, ka tas var būt diezgan mulsinoši, bet apskatīsim to ar vienkāršu grafiku.

Ir vairāki veidi, kā mēs varam vizualizēt procesu, kas darbojas mūsu datorā. Piemēram, UNIX (Linux un MAC) mums ir htop, kas ir interaktīvs procesa skatītājs.

Koka režīms ir visnoderīgākais rīks, lai apskatītu darbojošos apakšprocesus. Mēs to varam aktivizēt ar F5.

Ja mēs rūpīgi aplūkojam komandu sadaļu, mēs varam pamanīt mūsu datorā strādājošo procesu struktūru.

Viss sākas ar /sbin/init kas ir komanda, kas sāk katru procesu mūsu datorā. No šī brīža mēs varam redzēt citu procesu, piemēram, xfce4-screenshoter un xfce4-termināla, sākumu (kas veicina vēl vairāk apakšprocesu)

Aplūkojot Windows, mums ir mītisks uzdevumu pārvaldnieks kas ir noderīgi, iznīcinot šīs avārijas programmas mūsu datorā.

Tagad mums ir kristāldzidra koncepcija. Apskatīsim, kā Python var ieviest apakšprocesus.

Apakšprocesi Python

Python apakšprocess ir uzdevums, ko python skripts deleģē operētājsistēmai (OS).

Apakšprocesu bibliotēka ļauj mums izpildīt un pārvaldīt apakšprocesus tieši no Python. Tas ietver darbu ar standarta ievades stdin, standarta izvades stdout un atgriešanas kodiem.

Mums tas nav jāinstalē, izmantojot PIP, jo tā ir daļa no Python standarta bibliotēka.

Tāpēc mēs varam sākt izmantot python apakšprocesus, vienkārši importējot moduli.

import subprocess

# Using the module ....

Piezīme. Lai turpinātu šo rakstu, jums ir jābūt Python 3.5+

Lai pārbaudītu pašreizējo Python versiju, vienkārši palaidiet.

❯ python --version
Python 3.9.5 # My result

Ja iegūtā Python versija ir 2.x, varat izmantot šādu komandu

python3 --version

Turpinot tēmu, apakšprocesu bibliotēkas galvenā ideja ir spēja mijiedarboties ar OS, izpildot jebkuras vēlamās komandas tieši no Python tulka.

Tas nozīmē, ka mēs varam darīt visu, ko vēlamies, ja vien to atļauj mūsu operētājsistēma (un kamēr jūs nenoņemat saknes failu sistēmu 😅).

Apskatīsim, kā to izmantot, izveidojot vienkāršu skriptu, kurā uzskaitīti pašreizējā direktorija faili.

Pirmā apakšprocesa lietojumprogramma

Vispirms izveidosim failu list_dir.py. Šis būs fails, kurā mēs eksperimentēsim ar failu sarakstu.

touch list_dir.py

Tagad atvērsim šo failu un izmantosim šādu kodu.

import subprocess 

subprocess.run('ls')

Pirmkārt, mēs importējam apakšprocesa moduli un pēc tam, izmantojot funkciju palaist, kas tiek palaista, komanda, kuru mēs nododam kā argumentu.

  Cilņu grupu palīgs padara ciļņu pārvaldību pārlūkprogrammā Firefox pieejamāku

Šī funkcija tika ieviesta Python 3.5 kā draudzīgs saīsne uz apakšprocess.Atvērt. Funkcija subprocess.run ļauj mums palaist komandu un gaidīt, līdz tā tiks pabeigta, atšķirībā no Popen, kur mums ir iespēja izsaukt saziņu vēlāk.

Runājot par koda izvadi, ls ir UNIX komanda, kurā ir uzskaitīti faili tajā direktorijā, kurā atrodaties. Tāpēc, ja palaižat šo komandu, jūs iegūsit pašreizējā direktorijā esošo failu sarakstu.

❯ python list_dir.py
example.py  LICENSE  list_dir.py  README.md

Piezīme. Ņemiet vērā, ka, ja izmantojat operētājsistēmu Windows, jums būs jāizmanto dažādas komandas. Piemēram, “ls” vietā varat izmantot “dir”

Tas var šķist pārāk vienkārši, un jums ir taisnība. Jūs vēlaties pilnībā izmantot visu čaulas sniegto spēku. Tātad, iemācīsimies nodot argumentus apvalkam ar apakšprocesu.

Piemēram, lai uzskaitītu arī slēptos failus (tos, kas sākas ar punktu), kā arī uzskaitītu visus failu metadatus, mēs ierakstām šādu kodu.

import subprocess

# subprocess.run('ls')  # Simple command

subprocess.run('ls -la', shell=True)

Mēs palaižam šo komandu kā virkni un izmantojam argumentu apvalku. Tas nozīmē, ka mēs izsaucam čaulu mūsu apakšprocesa izpildes sākumā, un komandas argumentu tieši interpretē apvalks.

Tomēr use shell=True ir daudz mīnusu, un vissliktākās ir iespējamās drošības noplūdes. Par tiem varat lasīt sadaļā oficiālā dokumentācija.

Labākais veids, kā nodot komandas izpildes funkcijai, ir izmantot sarakstu, kurā lst[0] ir komanda izsaukt (šajā gadījumā ls) un lst[n] ir šīs komandas argumenti.

Ja mēs to darīsim, mūsu kods izskatīsies šādi.

import subprocess

# subprocess.run('ls')  # Simple command

# subprocess.run('ls -la', shell=True) # Dangerous command

subprocess.run(['ls', '-la'])

Ja mēs vēlamies saglabāt apakšprocesa standarta izvadi mainīgajā, mēs to varam izdarīt, iestatot argumentu Capture_output uz True.

list_of_files = subprocess.run(['ls', '-la'], capture_output=True)

print(list_of_files.stdout)

❯ python list_dir.py 
b'total 36ndrwxr-xr-x 3 daniel daniel 4096 may 20 21:08 .ndrwx------ 30 daniel daniel 4096 may 20 18:03 ..n-rw-r--r-- 1 daniel daniel 55 may 20 20:18 example.pyndrwxr-xr-x 8 daniel daniel 4096 may 20 17:31 .gitn-rw-r--r-- 1 daniel daniel 2160 may 17 22:23 .gitignoren-rw-r--r-- 1 daniel daniel 271 may 20 19:53 internet_checker.pyn-rw-r--r-- 1 daniel daniel 1076 may 17 22:23 LICENSEn-rw-r--r-- 1 daniel daniel 216 may 20 22:12 list_dir.pyn-rw-r--r-- 1 daniel daniel 22 may 17 22:23 README.mdn'

Lai piekļūtu procesa izvadei, mēs izmantojam instances atribūtu stdout.

Šajā gadījumā mēs vēlamies saglabāt izvadi kā virkni, nevis baitus, un mēs to varam izdarīt, iestatot teksta argumentu kā patiesu.

list_of_files = subprocess.run(['ls', '-la'], capture_output=True, text=True)

print(list_of_files.stdout)

❯ python list_dir.py
total 36
drwxr-xr-x  3 daniel daniel 4096 may 20 21:08 .
drwx------ 30 daniel daniel 4096 may 20 18:03 ..
-rw-r--r--  1 daniel daniel   55 may 20 20:18 example.py
drwxr-xr-x  8 daniel daniel 4096 may 20 17:31 .git
-rw-r--r--  1 daniel daniel 2160 may 17 22:23 .gitignore
-rw-r--r--  1 daniel daniel  271 may 20 19:53 internet_checker.py
-rw-r--r--  1 daniel daniel 1076 may 17 22:23 LICENSE
-rw-r--r--  1 daniel daniel  227 may 20 22:14 list_dir.py
-rw-r--r--  1 daniel daniel   22 may 17 22:23 README.md

Lieliski, tagad, kad mēs zinām apakšprocesu bibliotēkas pamatus, ir pienācis laiks pāriet pie dažiem lietošanas piemēriem.

  Sāciet savu biļetenu un pelniet naudu ar šiem risinājumiem

Lietojuma piemēri apakšprocesu Python

Šajā sadaļā mēs apskatīsim dažus apakšprocesu bibliotēkas praktiskos lietojumus. Jūs varat pārbaudīt tos visus šajā sadaļā Github repozitorijs.

Programmu pārbaudītājs

Viens no galvenajiem šīs bibliotēkas lietojumiem ir iespēja veikt vienkāršas operētājsistēmas darbības.

Piemēram, vienkāršs skripts, kas pārbauda, ​​vai programma ir instalēta. Operētājsistēmā Linux mēs to varam izdarīt ar komandu what.

'''Program checker with subprocess'''

import subprocess

program = 'git'

process = subprocess. run(['which', program], capture_output=True, text=True)

if process.returncode == 0: 
    print(f'The program "{program}" is installed')

    print(f'The location of the binary is: {process.stdout}')
else:
    print(f'Sorry the {program} is not installed')

    print(process.stderr)

Piezīme. Ja komanda UNIX ir veiksmīga, tās statusa kods ir 0. Pretējā gadījumā izpildes laikā radās kļūda

Tā kā mēs neizmantojam argumentu shell=True, mēs varam droši uztvert lietotāja ievadīto informāciju. Mēs varam arī pārbaudīt, vai ievade ir derīga programma ar regex modeli.

import subprocess

import re

programs = input('Separe the programs with a space: ').split()

secure_pattern = 'An'

for program in programs:

    if not re.match(secure_pattern, program):
        print("Sorry we can't check that program")

        continue

    process = subprocess. run(
        ['which', program], capture_output=True, text=True)

    if process.returncode == 0:
        print(f'The program "{program}" is installed')

        print(f'The location of the binary is: {process.stdout}')
    else:
        print(f'Sorry the {program} is not installed')

        print(process.stderr)

    print('n')

Šajā gadījumā mēs saņemam programmas no lietotāja un izmantojam regulāras izteiksmes izteiksmi, kas apliecina, ka programmas virknē ir tikai burti un cipari. Mēs pārbaudām katras programmas esamību ar for a cilpu.

Vienkāršs Grep programmā Python

Jūsu draugam Tomam ir modeļu saraksts teksta failā un vēl viens liels fails, kurā viņš vēlas iegūt atbilstības skaitu katram rakstam. Viņš pavadīja stundas, izpildot grep komandu katram modelim.

Par laimi, jūs zināt, kā atrisināt šo problēmu ar Python, un jūs palīdzēsit viņam paveikt šo uzdevumu dažu sekunžu laikā.

import subprocess

patterns_file="patterns.txt"
readfile="romeo-full.txt"

with open(patterns_file, 'r') as f:
    for pattern in f:
        pattern = pattern.strip()

        process = subprocess.run(
            ['grep', '-c', f'{pattern}', readfile], capture_output=True, text=True)

        if int(process.stdout) == 0:
            print(
                f'The pattern "{pattern}" did not match any line of {readfile}')

            continue

        print(f'The pattern "{pattern}" matched {process.stdout.strip()} times')

Apskatot šo failu, mēs definējam divus mainīgos, kas ir failu nosaukumi, ar kuriem mēs vēlamies strādāt. Pēc tam atveram failu, kurā ir visi modeļi, un atkārtojam tos. Tālāk mēs izsaucam apakšprocesu, kas izpilda grep komandu ar karogu “-c” (nozīmē skaitīšanu) un nosaka atbilstības izvadi ar nosacījumu.

Ja palaižat šo failu (atcerieties, ka varat lejupielādēt teksta failus no Github repo)

Iestatiet virtualenv ar apakšprocesu

Viena no stilīgākajām lietām, ko varat darīt ar Python, ir procesu automatizācija. Šāda veida skripts var ietaupīt stundas nedēļā.

Piemēram, mēs izveidosim iestatīšanas skriptu, kas mums izveido virtuālo vidi un mēģina pašreizējā direktorijā atrast failu prasības.txt, lai instalētu visas atkarības.

import subprocess

from pathlib import Path


VENV_NAME = '.venv'
REQUIREMENTS = 'requirements.txt'

process1 = subprocess.run(['which', 'python3'], capture_output=True, text=True)

if process1.returncode != 0:
    raise OSError('Sorry python3 is not installed')

python_bin = process1.stdout.strip()

print(f'Python found in: {python_bin}')

process2 = subprocess.run('echo "$SHELL"', shell=True, capture_output=True, text=True)

shell_bin = process2.stdout.split('/')[-1]

create_venv = subprocess.run([python_bin, '-m', 'venv', VENV_NAME], check=True)

if create_venv.returncode == 0:
    print(f'Your venv {VENV_NAME} has been created')

pip_bin = f'{VENV_NAME}/bin/pip3'

if Path(REQUIREMENTS).exists():
    print(f'Requirements file "{REQUIREMENTS}" found')
    print('Installing requirements')
    subprocess.run([pip_bin, 'install', '-r', REQUIREMENTS])

    print('Process completed! Now activate your environment with "source .venv/bin/activate"')

else:
    print("No requirements specified ...")

  Kā izmantot balss tērzēšanu H1Z1 PS4

Šajā gadījumā mēs izmantojam vairākus procesus un parsējam datus, kas mums nepieciešami mūsu python skriptā. Mēs arī izmantojam pathlib bibliotēka, kas ļauj mums to izdomāt, ja fails prasības.txt pastāv.

Ja palaižat python failu, jūs saņemsit dažus noderīgus ziņojumus par to, kas notiek ar OS.

❯ python setup.py 
Python found in: /usr/bin/python3
Your venv .venv has been created
Requirements file "requirements.txt" found
Installing requirements
Collecting asgiref==3.3.4 .......
Process completed! Now activate your environment with "source .venv/bin/activate"

Ņemiet vērā, ka mēs iegūstam instalēšanas procesa izvadi, jo mēs nenovirzām standarta izvadi uz mainīgo.

Palaidiet citu programmēšanas valodu

Mēs varam palaist citas programmēšanas valodas ar python un iegūt izvadi no šiem failiem. Tas ir iespējams, jo apakšprocesi tieši mijiedarbojas ar operētājsistēmu.

Piemēram, izveidosim programmu hello world C++ un Java. Lai izpildītu tālāk norādīto failu, jums būs jāinstalē C++ un Java kompilatori.

helloworld.cpp

#include <iostream>

int main(){
    std::cout << "This is a hello world in C++" << std::endl;
    return 0;
}

helloworld.java

class HelloWorld{  
    public static void main(String args[]){  
     System.out.println("This is a hello world in Java");  
    }  
}  

Es zinu, ka tas šķiet daudz koda, salīdzinot ar vienkāršu Python viena līnijpārvadātāju, taču tas ir tikai testēšanas nolūkos.

Mēs izveidosim Python skriptu, kas palaiž visus C++ un Java failus direktorijā. Lai to izdarītu, vispirms mēs vēlamies iegūt failu sarakstu atkarībā no faila paplašinājuma un glob ļauj mums to izdarīt viegli!

from glob import glob

# Gets files with each extension
java_files = glob('*.java')

cpp_files = glob('*.cpp')

Pēc tam mēs varam sākt izmantot apakšprocesus, lai izpildītu katra veida failu.

for file in cpp_files:
    process = subprocess.run(f'g++ {file} -o out; ./out', shell=True, capture_output=True, text=True)
    
    output = process.stdout.strip() + ' BTW this was runned by Python'

    print(output)

for file in java_files:
    without_ext = file.strip('.java')
    process = subprocess.run(f'java {file}; java {without_ext}',shell=True, capture_output=True, text=True)

    output = process.stdout.strip() + ' A Python subprocess runned this :)'
    print(output)

Viens neliels triks ir izmantot virknes funkciju joslu, lai modificētu izvadi un iegūtu tikai to, kas mums nepieciešams.

Piezīme. Esiet uzmanīgi, lai palaistu lielus Java vai C++ failus, jo mēs ielādējam to izvadi atmiņā un tas var izraisīt atmiņas noplūdi.

Atveriet ārējās programmas

Mēs varam palaist citas programmas, vienkārši izsaucot to bināro failu atrašanās vietu, izmantojot apakšprocesu.

Izmēģināsim to, atverot brave, manu iecienīto tīmekļa pārlūkprogrammu.

import subprocess

subprocess.run('brave')

Tiks atvērts pārlūkprogrammas gadījums vai tikai cita cilne, ja pārlūkprogramma jau darbojas.

Tāpat kā ar jebkuru citu programmu, kas pieņem karogus, mēs varam tos izmantot, lai radītu vēlamo darbību.

import subprocess

subprocess.run(['brave', '--incognito'])

Sasummēt

Apakšprocess ir datora process, ko rada cits process. Mēs varam pārbaudīt procesus, kas darbojas mūsu datorā, izmantojot tādus rīkus kā htop un uzdevumu pārvaldnieks.

Python ir sava bibliotēka darbam ar apakšprocesiem. Pašlaik palaišanas funkcija sniedz mums vienkāršu saskarni, lai izveidotu un pārvaldītu apakšprocesus.

Mēs varam ar tiem izveidot jebkāda veida lietojumprogrammas, jo mēs tieši mijiedarbojamies ar OS.

Visbeidzot, atcerieties, ka labākais veids, kā mācīties, ir izveidot kaut ko, ko vēlaties izmantot.