Home » 레퍼런스 » PYTHON » 파이썬 subprocess run 함수로 return code를 얻어와 봅시다.

파이썬 subprocess run 함수로 return code를 얻어와 봅시다.

문제 세팅을 위해 로컬 스트레스를 돌리는 경우가 왕왕 있습니다. 이럴 때 파이썬 스크립트를 자주 사용하는 편입니다. 스트레스를 돌릴 때, diff 함수를 상당히 자주 사용합니다. 수만개의 스트레스를 자동으로 돌리는 방법이 없을까요? 이 글에서는 subprocess run 함수로 이러한 일을 하는 방법을 알아봅니다.


명령어 결과 얻어오기

test/diff 디렉토리에 1.in, 2.in, 3.in 이렇게 3개의 파일이 있습니다.

[그림 1] 1.in, 2.in, 3.in 함수

1.in과 2.in에는 1이, 3.in에는 3이 있습니다. diff는 몇 개의 파일을 비교하는데요. 두 개의 파일을 비교할 때 리턴값은 아래와 같습니다.

  • 두 파일이 같으면 0
  • 두 파일이 다르면 1
  • 에러가 발생하면 2

실행을 시켜 보겠습니다.

[그림 2] 1.in과 2.in을 비교하기

diff 1.in 2.in 명령어를 실행시켰습니다. 그리고 echo $?를 실행시켰습니다. 여기서, $?는 이전에 실행한 명령어의 리턴값을 가져옵니다. diff는 두 파일이 같으면 0을 리턴합니다. 1.in과 2.in은 같은 내용이 있었기 때문에, 0을 돌려줍니다.

[그림 3] 1.in과 3.in을 비교하기

반대로, 1.in과 3.in을 비교해 봅시다. 1.in에는 1이 있지만 3.in에는 3이 있습니다. 둘이 다릅니다. 따라서, 1이 리턴되게 됩니다. 두 솔루션을 비교할 때, 결과 파일 2개를 diff의 리턴값으로 비교하면 된다는 것을 알 수 있습니다. local stress 어렵지 않게 구축 가능합니다.


파이썬 subprocess run 함수의 returncode 알아보기

이제, 문제의 함수를 보도록 합시다.

[그림 4] run 함수

엄청나게 많은 인자들이 있습니다. 이 글에서 언급하는 keyword는 2개입니다.

  • args
  • stdout

args는 명령어를 의미합니다. 예를 들어, ls -l의 경우 [“ls”, “-l”]을 넘겨주면 됩니다. 맨 밑에 보시면, 인자로 넘겨준 args를 가지고 command를 돌립니다. 그리고, CompletedProcess 인스턴스를 돌려준다고 되어 있어요.

[그림 5] CompletedProcess 인스턴스

이 CompletedProcess 인스턴스에는 returncode가 있습니다. 명령어를 실행한 후의 exitcode 입니다. 이것이 핵심입니다. diff로 두 파일을 비교하는 명령어를 실행시켰다면 어떤 값이 저장될까요?

  • 두 파일이 같다면 0
  • 두 파일이 다르다면 1
  • 에러가 발생하면 2

이제, 예제를 보도록 하겠습니다.

[그림 6] 예제 1번 프로그램

먼저 1번 예제입니다. run의 args로 [“diff”, “1.in”, “2.in”]을 넘겨주었습니다. 이는 “diff 1.in 2.in” 명령어를 실행한다는 의미입니다. 이 명령어의 exitCode를 받는데, 같기 때문에 0을 받습니다. 다음, 2번째 run은 “diff 1.in 3.in”을 실행합니다. 1.in과 3.in은 다르기 때문에 1이 리턴됩니다. 결과를 볼까요?

[그림 7] 예제 1번의 결과

0과 1이 나옵니다. 그런데, 중간에 출력이 들어갑니다. 이는, diff 명령어가 두 파일이 다르면 stdout에 출력해 버리기 때문입니다.

여기서 핵심은 파이썬 subprocess run 함수가 CompletedProcess 인스턴스를 리턴합니다. 이 리턴값의 returncode를 가져오면 명령어의 리턴값을 얻어올 수 있게 됩니다.


diff 출력 제외하기

run 함수를 실행시킬 때, diff 함수의 출력을 제외하려면 어떻게 해야 할까요? 간단합니다. stdout을 표준 출력으로 하는 것이 아니라, 다른 파일로 해 버리면 됩니다. subprocess.DEVNULL은 아무 파일에도 출력하지 않고 버립니다.

[그림 8] 예제 2번 프로그램

예제 2번 프로그램을 보겠습니다. 2번째 run 함수의 stdout에 subprocess.DEVNULL을 넘겨주었습니다. 이는, 명령어를 실행시키는 프로세스의 표준 출력을 DEVNULL로 덮어쓴다는 의미입니다.

[그림 9] 예제 2번의 실행 결과

실행 결과는 위와 같습니다. 예제 1과는 다르게 다른 부분이 출력되지 않았습니다. 이는, 자식 프로세스인 diff의 output이 /dev/null로 출력했기 때문입니다. output 캡쳐하는 부분은 다음 글에 자세히 알아보도록 하겠습니다.

Leave a Comment

2 + 1 =