수년간의 bash 스크립팅 끝에 특정 조건이 충족될 때 쉘 스크립트를 호출하도록 Python 스크립트를 수정하는 작업이 주어졌습니다. 이 부분은 괜찮습니다. 하지만 이제 Python 스크립트에서 이 쉘 스크립트로 변수를 보내려고 하는데 길을 잃었습니다.
쉘 스크립트는 stdin을 사용하는데, 여기에 정수인 Python 변수 값을 넣으려고 합니다.
내 코드는 (지금까지) 다음과 같습니다.
if VAR > NUMBER:
import os
bashCommand = "echo something | /path/to/script --args"
os.system(bashCommand)
그리고 그것은 훌륭하게 작동합니다. 하지만 내가 원하는 것은 os.system(bashCommand)을 다음과 동일하게 만드는 것입니다:
echo $VAR | /path/to/script --args
심지어
echo 'some text' $VAR | /path/to/script --args
os.system이 작동하는 방식을 고려하면 내 접근 방식이 완전히 잘못된 것 같습니다.
그래서 내 질문은 VAR의 값을 bashCommand에, 바람직하게는 표준 입력으로 전달하는 방법입니다.
답변1
사용하지 마십시오 os.system()
. 모듈을 위해 더 이상 사용되지 않습니다 subprocess
.
귀하의 경우 모듈을 직접 사용할 수 있지만 , 셸에서 직접 명령을 실행하는 것은 안전하지 않으므로 subprocess
이 매개변수를 사용하지 않는 것이 좋습니다 . shell=True
필요한 모든 기능(예: 파이프)을 subprocess
모듈로 시뮬레이션할 수 있습니다.
이 예를 살펴보겠습니다.
import subprocess
var = 'foobar'
first = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'], stdin=first.stdout)
변수를 정의한 var
다음 해당 클래스를 사용하여 subprocess.Popen
값을 가져온 다음 해당 값을 파이프로 보냅니다. 이것은 수업의 대상입니다.var
/bin/echo
first
subprocess.Popen
그런 다음 via 파이프의 STDOUT을 STDIN으로 사용 first
하고 이에 따라 스크립트를 실행합니다.second
bash
명령의 출력을 문자열로 저장하려면 subprocess.check_output
다음과 같은 함수를 사용하십시오.
second = subprocess.check_output(['bash', '/path/to/script', '--args'], stdin=first.stdout)
읽다하위 프로세스 모듈에 대한 공식 문서더 많은 아이디어를 얻기 위해.
답변2
Python은 bash처럼 문자열의 변수를 확장하지 않습니다. Python이 있고 VAR
이를 bash에 전달하려면 다음을 수행할 수 있습니다.
subprocess.call('echo {} | /path/to/script --args'.format(VAR), shell=True)
VAR
확장하려는 bash 변수의 이름이 Python에 저장된 경우 다음과 같이 할 수 있습니다.
subprocess.call('echo "${}" | /path/to/script --args'.format(VAR), shell=True)
답변3
호출은 os.system()
더 이상 사용되지 않지만 여전히 작동합니다. 이 기능은 미래에 사라질 수 있으므로(아마 그럴 가능성이 높음) subprocess
하위 프로세스의 STDIN으로 데이터를 보내고 해당 STDOUT에서 읽는 매우 간단한 방법이 있는 모듈을 사용하여 이러한 호출을 리팩터링하는 것을 진지하게 고려할 수 있습니다.https://docs.python.org/2/library/subprocess.html
답변4
내 생각에 좋은 접근 방식은 다음과 같습니다.
var = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'],stdin=var.stdout, stdout=subprocess.PIPE)
var.stdout.close()
output = second.communicate()[0]
var.wait()