Python의 하위 프로세스는 무엇입니까? [5 Usage Examples]

하위 프로세스를 사용하면 운영 체제와 완전히 새로운 차원에서 상호 작용할 수 있습니다.

우리 컴퓨터는 항상 하위 프로세스를 실행합니다. 사실, 이 기사를 읽는 것만으로도 네트워크 관리자 또는 인터넷 브라우저 자체와 같은 많은 프로세스를 실행하고 있습니다.

이것에 대한 멋진 점은 우리가 컴퓨터에서 수행하는 모든 작업에는 하위 프로세스 호출이 포함된다는 것입니다. 파이썬으로 간단한 “hello world” 스크립트를 작성하는 경우에도 마찬가지입니다.

한동안 프로그래밍을 배웠더라도 하위 프로세스의 개념이 모호해 보일 수 있습니다. 이 기사에서는 하위 프로세스의 주요 개념과 Python을 사용하는 방법에 대해 자세히 살펴봅니다. 하위 프로세스 표준 라이브러리.

이 자습서를 마치면 다음을 수행하게 됩니다.

  • 하위 프로세스의 개념 이해
  • Python 하위 프로세스 라이브러리의 기본 사항을 배웠습니다.
  • 유용한 예제로 Python 기술 연습

그것에 들어가 보자

하위 프로세스의 개념

대체로 하위 프로세스는 컴퓨터 프로세스 다른 프로세스에 의해 생성됩니다.

하위 프로세스는 트리로 생각할 수 있으며 각 상위 프로세스에는 하위 프로세스가 실행되고 있습니다. 이것이 상당히 혼란스러울 수 있다는 것을 알고 있지만 간단한 그래픽으로 살펴보겠습니다.

컴퓨터에서 실행 중인 프로세스를 시각화할 수 있는 몇 가지 방법이 있습니다. 예를 들어 UNIX(Linux & MAC)에서는 htop, 대화식 프로세스 뷰어입니다.

트리 모드는 실행 중인 하위 프로세스를 살펴보는 데 가장 유용한 도구입니다. F5로 활성화할 수 있습니다.

명령 섹션을 자세히 살펴보면 컴퓨터에서 실행되는 프로세스의 구조를 알 수 있습니다.

모든 것은 /sbin/초기화 컴퓨터에서 각 프로세스를 시작하는 명령입니다. 그 시점부터 xfce4-screenshoter 및 xfce4-terminal과 같은 다른 프로세스의 시작을 볼 수 있습니다(더 많은 하위 프로세스로 이어짐).

Windows를 살펴보면 신화가 있습니다. 작업 관리자 이는 우리 시스템에서 충돌하는 프로그램을 죽일 때 유용합니다.

이제 우리는 명확한 개념을 가지고 있습니다. Python에서 하위 프로세스를 구현하는 방법을 살펴보겠습니다.

Python의 하위 프로세스

Python의 하위 프로세스는 Python 스크립트가 운영 체제(OS)에 위임하는 작업입니다.

하위 프로세스 라이브러리를 사용하면 Python에서 직접 하위 프로세스를 실행하고 관리할 수 있습니다. 여기에는 표준 입력 stdin, 표준 출력 stdout 및 반환 코드 작업이 포함됩니다.

Python의 일부이므로 PIP로 설치할 필요가 없습니다. 표준 라이브러리.

따라서 모듈을 가져오기만 하면 Python에서 하위 프로세스를 사용할 수 있습니다.

import subprocess

# Using the module ....

참고: 이 기사를 따라하려면 Python 3.5 이상이 있어야 합니다.

현재 가지고 있는 파이썬 버전을 확인하려면 실행하십시오.

❯ python --version
Python 3.9.5 # My result

얻는 Python 버전이 2.x인 경우 다음 명령을 사용할 수 있습니다.

python3 --version

계속해서 주제를 살펴보면 하위 프로세스 라이브러리의 기본 아이디어는 Python 인터프리터에서 직접 원하는 명령을 실행하여 OS와 상호 작용할 수 있다는 것입니다.

즉, OS가 허용하는 한(그리고 루트 파일 시스템을 제거하지 않는 한 😅) 원하는 것은 무엇이든 할 수 있습니다.

현재 디렉터리의 파일을 나열하는 간단한 스크립트를 만들어 사용 방법을 살펴보겠습니다.

  Facebook이 회원님에 대해 알고 있는 모든 정보를 확인하는 방법

첫 번째 하위 프로세스 애플리케이션

먼저 list_dir.py 파일을 생성해 보겠습니다. 이것은 우리가 목록 파일을 실험할 파일이 될 것입니다.

touch list_dir.py

이제 해당 파일을 열고 다음 코드를 사용하겠습니다.

import subprocess 

subprocess.run('ls')

먼저 하위 프로세스 모듈을 가져온 다음 실행되는 함수 실행을 사용하여 인수로 전달하는 명령입니다.

이 함수는 Python 3.5에서 친숙한 바로 가기로 도입되었습니다. 하위 프로세스.열기. subprocess.run 함수를 사용하면 나중에 통신을 호출할 수 있는 Popen과 달리 명령을 실행하고 완료될 때까지 기다릴 수 있습니다.

코드 출력에 대해 말하자면, ls는 현재 있는 디렉토리의 파일을 나열하는 UNIX 명령입니다. 따라서 이 명령을 실행하면 현재 디렉토리에 있는 파일 목록을 얻을 수 있습니다.

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

참고: Windows를 사용 중인 경우 다른 명령을 사용해야 한다는 점을 고려하세요. 예를 들어 “ls” 대신 “dir”을 사용할 수 있습니다.

이것은 너무 단순해 보일 수 있으며 당신 말이 맞습니다. 쉘이 제공하는 모든 기능에 완전히 접근하기를 원합니다. 이제 subprocess를 사용하여 쉘에 인수를 전달하는 방법을 알아봅시다.

예를 들어 숨겨진 파일(점으로 시작하는 파일)도 나열하고 파일의 모든 메타데이터도 나열하려면 다음 코드를 작성합니다.

import subprocess

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

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

이 명령을 문자열로 실행하고 인수 셸을 사용합니다. 즉, 하위 프로세스 실행이 시작될 때 쉘을 호출하고 명령 인수가 쉘에 의해 직접 해석됩니다.

그러나 사용 shell=True에는 많은 단점이 있으며 최악의 경우 보안 누출 가능성이 있습니다. 당신은 그들에 대해 읽을 수 있습니다 공식 문서.

실행 함수에 명령을 전달하는 가장 좋은 방법은 목록을 사용하는 것입니다.[0] (이 경우 ls) 및 lst를 호출하는 명령입니다.[n] 해당 명령의 인수입니다.

이렇게 하면 코드가 다음과 같이 됩니다.

import subprocess

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

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

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

하위 프로세스의 표준 출력을 변수에 저장하려면 capture_output 인수를 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'

프로세스의 출력에 액세스하기 위해 인스턴스 속성 stdout을 사용합니다.

이 경우 출력을 바이트 대신 문자열로 저장하려고 하며 text 인수를 true로 설정하면 됩니다.

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

완벽합니다. 이제 하위 프로세스 라이브러리의 기본 사항을 알았으므로 몇 가지 사용 예제로 넘어갈 차례입니다.

  성능을 추적하는 6가지 최고의 네트워크 관리 도구

Python에서 하위 프로세스의 사용 예

이 섹션에서는 하위 프로세스 라이브러리의 몇 가지 실용적인 사용을 검토할 것입니다. 이 항목에서 모두 확인할 수 있습니다. Github 리포지토리.

프로그램 체커

이 라이브러리의 주요 용도 중 하나는 간단한 OS 작업을 수행하는 기능입니다.

예를 들어 프로그램이 설치되어 있는지 확인하는 간단한 스크립트입니다. Linux에서는 which 명령으로 이를 수행할 수 있습니다.

'''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)

참고: UNIX에서 명령이 성공하면 상태 코드는 0입니다. 그렇지 않으면 실행 중에 문제가 발생한 것입니다.

shell=True 인수를 사용하지 않기 때문에 안전하게 사용자 입력을 받을 수 있습니다. 또한 정규식 패턴을 사용하여 입력이 유효한 프로그램인지 확인할 수 있습니다.

import subprocess

import re

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

secure_pattern = '토'

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')

이 경우 사용자로부터 프로그램을 받고 프로그램 문자열에 문자와 숫자만 포함되어 있음을 인증하는 정규 표현식을 사용합니다. for 루프를 사용하여 각 프로그램의 존재를 확인합니다.

Python의 간단한 Grep

당신의 친구 Tom은 텍스트 파일과 각 패턴에 대해 일치하는 수를 가져오려는 또 다른 큰 파일에 패턴 목록을 가지고 있습니다. 그는 모든 패턴에 대해 grep 명령을 실행하는 데 몇 시간을 소비했습니다.

다행스럽게도 여러분은 Python으로 이 문제를 해결하는 방법을 알고 있으며 그가 몇 초 안에 이 작업을 완료하도록 도울 것입니다.

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')

이 파일을 살펴보고 작업하려는 파일 이름인 두 개의 변수를 정의합니다. 그런 다음 모든 패턴이 포함된 파일을 열고 반복합니다. 다음으로 “-c” 플래그(카운트를 의미)와 함께 grep 명령을 실행하는 하위 프로세스를 호출하고 조건부로 일치 결과를 결정합니다.

이 파일을 실행하면(다음에서 텍스트 파일을 다운로드할 수 있음을 기억하십시오. Github 저장소)

하위 프로세스로 virtualenv 설정

Python으로 할 수 있는 가장 멋진 일 중 하나는 프로세스 자동화입니다. 이런 종류의 스크립트를 사용하면 일주일에 몇 시간을 절약할 수 있습니다.

예를 들어 가상 환경을 생성하고 현재 디렉토리에서 requirements.txt 파일을 찾아 모든 종속성을 설치하는 설정 스크립트를 생성할 것입니다.

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 ...")

  Microsoft Word 문서의 크기는 얼마나 큽니까?

이 경우 여러 프로세스를 사용하고 Python 스크립트에서 필요한 데이터를 구문 분석합니다. 우리는 또한 경로 라이브러리 requirements.txt 파일이 있는지 파악할 수 있는 라이브러리입니다.

파이썬 파일을 실행하면 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"

표준 출력을 변수로 리디렉션하지 않기 때문에 설치 프로세스에서 출력을 얻습니다.

다른 프로그래밍 언어 실행

파이썬으로 다른 프로그래밍 언어를 실행하고 해당 파일에서 출력을 얻을 수 있습니다. 이는 하위 프로세스가 운영 체제와 직접 상호 작용하기 때문에 가능합니다.

예를 들어 C++ 및 Java로 Hello World 프로그램을 만들어 봅시다. 다음 파일을 실행하려면 다음을 설치해야 합니다. C++ 그리고 자바 컴파일러.

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");  
    }  
}  

단순한 파이썬 원라이너에 비해 코드가 많아 보이지만 테스트 목적일 뿐입니다.

디렉토리에 있는 모든 C++ 및 Java 파일을 실행하는 Python 스크립트를 만들 것입니다. 이를 위해 먼저 파일 확장자에 따라 파일 목록을 얻고 싶습니다. 덩어리 우리가 쉽게 할 수 있습니다!

from glob import glob

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

cpp_files = glob('*.cpp')

그런 다음 하위 프로세스를 사용하여 각 유형의 파일을 실행할 수 있습니다.

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)

한 가지 작은 요령은 문자열 함수 strip을 사용하여 출력을 수정하고 필요한 것만 가져오는 것입니다.

참고: 출력을 메모리에 로드하고 메모리 누수가 발생할 수 있으므로 큰 Java 또는 C++ 파일을 실행할 때 주의하십시오.

외부 프로그램 열기

하위 프로세스를 통해 바이너리 위치를 호출하기만 하면 다른 프로그램을 실행할 수 있습니다.

내가 선호하는 웹 브라우저인 Brave를 열어서 사용해 봅시다.

import subprocess

subprocess.run('brave')

이렇게 하면 브라우저 인스턴스가 열리거나 이미 브라우저를 실행 중인 경우 다른 탭이 열립니다.

플래그를 허용하는 다른 프로그램과 마찬가지로 플래그를 사용하여 원하는 동작을 생성할 수 있습니다.

import subprocess

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

요약하자면

하위 프로세스는 다른 프로세스에 의해 생성된 컴퓨터 프로세스입니다. htop 및 작업 관리자와 같은 도구를 사용하여 컴퓨터에서 실행 중인 프로세스를 확인할 수 있습니다.

Python에는 하위 프로세스와 함께 작동하는 자체 라이브러리가 있습니다. 현재 실행 기능은 하위 프로세스를 만들고 관리할 수 있는 간단한 인터페이스를 제공합니다.

우리는 OS와 직접 상호 작용하기 때문에 모든 종류의 응용 프로그램을 만들 수 있습니다.

마지막으로, 배우는 가장 좋은 방법은 사용하고 싶은 것을 만드는 것임을 기억하십시오.