Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 Subprocess 모듈 활용법: 시스템 명령 실행부터 디스크 정보 추출까지

프로세스(Process)란 무엇인가?

Windows, macOS 또는 Linux에서 프로그램을 작성하고 실행하면 운영체제는 하나의 프로세스를 생성합니다. 이 프로세스는 CPU, RAM, 디스크 공간과 같은 시스템 자원을 사용하며, 운영체제 커널 내부의 데이터 구조에도 접근합니다. 각 프로세스는 다른 프로세스로부터 격리되어 있기 때문에, 다른 프로세스가 무엇을 하고 있는지 확인하거나 간섭할 수 없습니다.

참고: 이 글의 코드는 Linux 계열 시스템에서만 정상적으로 동작합니다. Windows에서 실행할 경우 예외(Exception)가 발생할 수 있습니다.

운영체제의 핵심 목표

운영체제(OS)의 두 가지 핵심 목표는 프로세스의 작업을 공평하게 분배하는 것과 사용자에게 신속하게 반응하는 것입니다. 이는 실행 중인 모든 프로세스를 지속적으로 추적하고, 각 프로세스에 짧은 실행 시간을 할당한 뒤 다른 프로세스로 전환하는 방식으로 구현됩니다. Windows의 작업 관리자(Task Manager), macOS의 활성 상태 보기(Activity Monitor), Linux의 top 명령어 같은 도구를 통해 현재 프로세스의 상태를 확인할 수 있습니다.

프로그래머라면 자신의 프로그램 안에서 직접 프로세스 데이터에 접근할 수도 있습니다. 어떻게 가능할까요? 바로 파이썬 표준 라이브러리인 os 모듈을 사용하면 됩니다. 몇 가지 예제를 통해 살펴보겠습니다.

# 이 스크립트는 linux/unix에서만 동작합니다
import os
print(f" *** Process ID - {os.getpid()}")
print(f" *** My User ID - {os.getuid()} and My Group ID - {os.getgid()} ")
print(f" *** Current Working Directory is - {os.getcwd()}")

새로운 시스템 프로세스를 생성하고 실행하는 기능은 특정 운영체제 작업을 자동화하려는 개발자와 시스템 관리자에게 매우 유용합니다.

파이썬의 subprocess 모듈은 새로운 프로세스를 생성하고, 해당 프로세스와 정보를 주고받으며, 오류와 반환 코드(return code)까지 처리할 수 있는 강력한 기능을 제공합니다.

실제로 공식 파이썬 문서에서도 시스템 명령어에 접근할 때 subprocess 모듈 사용을 권장하고 있습니다.

subprocess의 call() 함수는 호출된 명령이 출력을 모두 마칠 때까지 대기한 후 결과를 반환합니다. 아래에서 시스템의 디스크 공간 정보를 추출하는 몇 가지 예제를 소개합니다.

다음 코드는 df -h 명령어를 실행하여 디스크 정보를 캡처하고, 그 출력 결과를 pandas 데이터프레임으로 변환하여 추가적인 처리에 활용합니다.

예제 1: df -h 명령으로 디스크 공간 추출하기

# python code to create a subprocess for extracting disk space on linux using df -h

from io import StringIO
import pandas as pd
import subprocess
import ast
diskspace = "df"
diskspace_arg = "-h"

sp = subprocess.Popen([diskspace,diskspace_arg], stdout=subprocess.PIPE)
b = StringIO(sp.communicate()[0].decode('utf-8'))
df = pd.read_csv(b, sep=",")
print(df)

실행 결과

<_io.StringIO object at 0x7ff67ef52798>
Filesystem Size Used Avail Use% Mounted on
0 devtmpfs 7.8G 0 7.8G 0% /dev
1 tmpfs 7.8G 0 7.8G 0% /dev/shm
2 tmpfs 7.8G 33M 7.8G 1% /run
3 tmpfs 7.8G 0 7.8G 0% /sys/fs/...
4 /dev/xvda2 20G 16G 4.3G 79% /
5 /dev/xvdb 246G 16G 218G 7% /tdm
6 tmpfs 1.6G 0 1.6G 0% /run/use...

예제 2: 더 자세한 출력 얻기

subprocess를 활용해 더욱 상세한 시스템 정보를 출력하려면 아래 코드를 참고하세요. 이 예제에서는 call()check_output() 두 가지 방식을 함께 사용합니다.

from io import StringIO
import pandas as pd
import subprocess
def uname_func():
uname = "uname"
uname_arg = "-a"
user_info = subprocess.call([uname, uname_arg])
return user_info

def disk_func():
diskspace = "pydf"
diskspace_arg = "-a"
discinfo_df = diskspace
stdout = subprocess.check_output([diskspace, diskspace_arg])
return stdout

def main():
userinfo = uname_func()
discinfo = disk_func()
print("Displaying values now... ")
# print(stdout.decode('utf-8'))
print(discinfo.decode('utf-8'))
print(type(discinfo.decode('utf-8')))
content = discinfo.decode('utf-8').split("\n")
print(content)

main()

실행 결과

Linux ip-00-000-00-000.xxxx.xxxx.xx.xx 0.00.0-000.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020 x86_64 x86_64 x86_64 GNU/Linux
Displaying values now...
Filesystem Size Used Avail Use% Mounted on
/dev/xvda2 20G 16G 4318M 78.9 [#####.] /
devtmpfs 7918M 0 7918M 0.0 [......] /dev
hugetlbfs 0 0 0 - [......] /dev/hugepages
mqueue 0 0 0 - [......] /dev/mqueue
devpts 0 0 0 - [......] /dev/pts
tmpfs 7942M 0 7942M 0.0 [......] /dev/shm
proc 0 0 0 - [......] /proc
binfmt_misc 0 0 0 - [......] /proc/sys/fs/binfmt_misc
tmpfs 7942M 32M 7909M 0.4 [......] /run
tmpfs 1588M 0 1588M 0.0 [......] /run/user/1000
sysfs 0 0 0 - [......] /sys
tmpfs 7942M 0 7942M 0.0 [......] /sys/fs/cgroup
cgroup 0 0 0 - [......] /sys/fs/cgroup/blkio
cgroup 0 0 0 - [......] /sys/fs/cgroup/cpu,cpuacct
cgroup 0 0 0 - [......] /sys/fs/cgroup/cpuset
cgroup 0 0 0 - [......] /sys/fs/cgroup/devices
cgroup 0 0 0 - [......] /sys/fs/cgroup/freezer
cgroup 0 0 0 - [......] /sys/fs/cgroup/hugetlb
cgroup 0 0 0 - [......] /sys/fs/cgroup/memory
cgroup 0 0 0 - [......] /sys/fs/cgroup/net_cls,net_prio
cgroup 0 0 0 - [......] /sys/fs/cgroup/perf_event
cgroup 0 0 0 - [......] /sys/fs/cgroup/pids
cgroup 0 0 0 - [......] /sys/fs/cgroup/systemd
pstore 0 0 0 - [......] /sys/fs/pstore
configfs 0 0 0 - [......] /sys/kernel/config
debugfs 0 0 0 - [......] /sys/kernel/debug
securityfs 0 0 0 - [......] /sys/kernel/security
/dev/xvdb 246G 16G 218G 6.4 [......] /tdm