Gabay sa subprocess ng Python: Simula hanggang Advanced

1. Ano ang subprocess module ng Python

Pangkalahatang Ideya

Ang subprocess module ng Python ay isang makapangyarihang tool para magpatakbo ng mga utos sa systema o mga panlabas na programa mula sa Python. Sa paggamit ng module na ito, nagiging posible ang pamamahala ng standard input/output at mga proseso, at pinapasimple ang pakikipag-ugnayan ng Python program at mga panlabas na programa. Bilang kapalit ng tradisyonal na os.system() at commands module, nag-aalok ito ng mas ligtas at mas flexible na kontrol sa mga proseso.

Pangunahing Gamit

  • Pagpapatakbo ng Shell Command: Pagpatawag ng simpleng system command.
  • Pamahala ng Proseso: Pagpapatakbo ng panlabas na programa at pag-redirect ng standard input/output.
  • Asynchronous Processing: Pamamahala ng mga gawain na matagal tumagal o mga gawain na isinasagawa nang sabay-sabay.

2. Pangunahing Paggamit: subprocess.run()

Pangunahing Paggamit

subprocess.run() ay isang function para simple na magpatakbo ng mga system command mula sa Python. Halimbawa, kung nais mong ilista ang mga file sa isang directory, gamitin ang sumusunod na code.
import subprocess

result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
Ang code na ito ay nagpapatakbo ng ls -l command, iniimbak ang output nito sa stdout, at pinoproseso ito sa Python. Sa pamamagitan ng capture_output=True, nakukuha ang standard output, at sa code> ang resulta ay tinatrato bilang string.

Paghawak ng Error

subprocess.run() ay maaaring gamitin upang kunin ang mensahe ng error gamit ang stderr kapag nabigo ang command. Maaari mo ring suriin ang tagumpay o kabiguan ng pagpapatupad gamit ang returncode.
result = subprocess.run(['ls', 'nonexistentfile'], capture_output=True, text=True)
if result.returncode != 0:
    print(f"Error: {result.stderr}")
Sa halimbawang ito, kapag nagtakda ng hindi umiiral na file, magpapakita ang standard error ng mensahe ng error.

3. Asynchronous na Pagpapatupad:subprocess.Popen()

Asynchronous na pagproseso gamit ang Popen

subprocess.run() ay synchronous na proseso, kaya hindi makakagalaw ang programang Python sa susunod na hakbang hanggang matapos ang command, ngunit kapag ginamit ang subprocess.Popen(), maaaring patakbuhin ang proseso nang asynchronous at magsagawa ng iba pang mga gawain nang sabay-sabay.
import subprocess

proc = subprocess.Popen(['sleep', '5'], stdout=subprocess.PIPE)
print("Nagsimula na ang proseso")
proc.wait()
print("Natapos na ang proseso")
Sa code na ito, ang sleep 5 ay isinasagawa nang asynchronous, kaya maaaring magpatuloy sa ibang mga gawain habang ito ay tumatakbo.

Pagkontrol sa Standard Input/Output

Popen ay maaaring detalyadong kontrolin ang pag-redirect ng standard input at output. Halimbawa, ang sumusunod na code ay nagbabasa ng data mula sa isang file, pinoproseso gamit ang command na cat, at nagsusulat sa ibang file.
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
    proc = subprocess.Popen(['cat'], stdin=infile, stdout=outfile)
    proc.wait()
Sa ganitong paraan, maaaring i-redirect ang standard input at output ng external command sa mga file para maproseso.

4. Halimbawa ng Paggamit: Script ng Awtomasyon

Pag-backup ng File

Ang subprocess ay napaka-kapaki-pakinabang sa pamamahala ng sistema at awtomasyon ng mga regular na gawain. Halimbawa, sa susunod na halimbawa, awtomatikong kinokopya ang mga file sa backup directory.
import subprocess

files_to_backup = ['file1.txt', 'file2.txt', 'file3.txt']
backup_dir = '/backup/directory/'

for file in files_to_backup:
    subprocess.run(['cp', file, backup_dir])
Ang code na ito ay kumokopya ng tinukoy na mga file sa backup folder. Sa pamamagitan ng paggawa ng ganitong simpleng script, maaaring i-automate ang regular na mga gawain sa backup.

Paggamit sa CI/CD Pipeline

Ang subprocess ay ginagamit din sa mga kapaligiran ng patuloy na integrasyon (CI) at patuloy na paghahatid (CD), at isinasama bilang bahagi ng awtomatikong pagpapatakbo ng mga test script at proseso ng pag-deploy. Halimbawa, maaaring patakbuhin ang test script, at kung matagumpay, magpatuloy sa susunod na hakbang, na nagpapahintulot ng ganitong uri ng awtomasyon.
年収訴求

5. Seguridad at Pinakamainam na Kasanayan

Panganib ng shell=True

shell=True Ang opsyong shell=True ay ginagamit kapag nagpapatakbo ng mga utos pamamagitan ng shell, ngunit may kasamang panganib sa seguridad. Lalo na kapag direktang ipinapasa ang input mula sa labas, may panganib ng shell injection attack. Sa paggamit ng shell=False, maaaring mabawasan ang panganib na ito.
import subprocess

# Inirerekomendang paraan (ligtas)
subprocess.run(['ls', '-l'])

# shell=True (mag-ingat)
subprocess.run('ls -l', shell=True)

Suporta sa Cross-Platform

Ang mga system command ay maaaring gumamit ng magkaibang mga utos depende sa iba’t ibang kapaligiran ng OS. Gamit ang Python platform module, maaari mong palitan ang utos na ipapatupad batay sa OS tulad ng ipinapakita sa ibaba.
import platform
import subprocess

if platform.system() == "Windows":
    subprocess.run(['dir'], shell=True)
else:
    subprocess.run(['ls', '-l'])

6. Pag-troubleshoot at Debugging

Pangkaraniwang mga Error at Mga Solusyon

subprocess kapag ginagamit, madalas na nagkakaroon ng mga error tulad ng hindi makita ang file o walang sapat na pahintulot. Maaari mong kunin ang mga detalye ng error sa pamamagitan ng pag-capture gamit ang stderr at pag-check ng returncode.

Mga Tip para sa Debugging

check=True kapag ginagamit, magtataas ito ng exception kapag nabigo ang command, na nagbibigay-daan upang maagap na matukoy ang problema. Bukod pa rito, ang pag-capture ng standard output at mga mensahe ng error at pag-save nito sa log ay nagpapadali ng debugging.
import subprocess

try:
    result = subprocess.run(['ls', '-l'], check=True, capture_output=True, text=True)
    print(result.stdout)
except subprocess.CalledProcessError as e:
    print(f"Nagkaroon ng error: {e}")

7. Asynchronous na pagproseso at pakikipag-ugnayan sa asyncio

Asynchronous na pagproseso gamit ang asyncio

asyncio gamit, maaari mong iugnay ito sa subprocess at magproseso ng maraming proseso nang sabay-sabay at asynchronous. Ang sumusunod na halimbawa ay gumagamit ng asyncio upang patakbuhin ang ls command nang asynchronous at i-capture ang resulta.
import asyncio
import subprocess

async def run_command():
    proc = await asyncio.create_subprocess_exec('ls', '-l',
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    stdout, stderr = await proc.communicate()

    if stdout:
        print(f'[stdout]n{stdout.decode()}')
    if stderr:
        print(f'[stderr]n{stderr.decode()}')

asyncio.run(run_command())
Ang code na ito ay nagpapatakbo ng command nang asynchronous at pinoproseso ang mga resulta ng standard output at standard error. asyncio gamit, maaari mong epektibong pamahalaan ang mga asynchronous na gawain.