프로젝트 중 파이썬의 subprocess.check_output의 리턴값인 string을 다시 dict(json.load)로 변환하는 과정에서 문제가 발생했다.

 

 

 

subprocess모듈의 check_output은 다른 프로세스에서 수행된 print 값을 모두 모아 하나의 string으로 반환해준다.

그런데 dict를 print 해서 string으로 나온 것을 다시 json.load 함수를 써서 dict로 바꾸려니 온갖 DecodeError가 떴다.

 

작은 따옴표를 큰 따옴표로 바꾸고 '\'을 '\\'로 바꾸라는 둥 replace를 해결책으로 권하는 사람들이 많았는데

여간 귀찮은게 아닌데다 나는 딕셔너리의 value 내에 큰따옴표로 바꾸면 안되는 작은 따옴표들도 들어있어서 난감했다.

 

 


 

 

여기서 상당히 간단한 해결책이 있다.

ast 모듈eval()함수를 활용하면 된다.

 

import ast
import subprocess

result = subprocess.check_output([쉘 명령어], encoding='utf-8')
#result : "{'key': 'value'}"

dict = ast.literal_eval(result)
#dict : {'key': 'value'}

 

literal_eval은 문자열 내의 파이썬 표현식을 인식하는 함수인데 

예를 들어 '10+10'문자열이 있다고 하면 eval을 거쳐서 20의 결과를 반환해주는 상당히 편리한 함수이다.

그래서 위 코드를 수행하면 문자열이 딕셔너리로 변환된다.

 

 

 

다만 파이썬에서는 eval함수 사용을 보안상 문제로 인해 사용을 자제하도록 권고하고 있다.

 

이 함수는 어떤 문자열이든 인증절차나 확인 없이 바로 코드로 인식해 수행해버리기 때문에

만약 외부에서 들어온 악의적인 해킹 코드가 문자열로 들어오고, 그 값이 eval 함수에 들어가면 코드로 변환해 수행해버린다. 서버를 부수거나 기밀정보를 빼돌리는 것이 얼마든지 가능해지는 것이다.

 

따라서 사용에 상당히 주의해야함은 맞다.

반응형

+ Recent posts