Python에서 쉘 프롬프트 얻기

Python에서 쉘 프롬프트 얻기

Python 스크립트에서 (zsh) 쉘 프롬프트를 얻고 싶습니다. 그냥 사용

import os
prompt = os.environ['PS1']

PS1일반적 으로 하위 프로세스로의 전달이 수행되지 않으므로 올바른 접근 방식은 아닌 것 같습니다 . env | grep PS쉘에서도 같은 방식 으로 실패합니다.

그래서 대화형 셸을 하위 프로세스로 시작하고 프롬프트에 대해 쿼리해야 한다는 결론에 도달했습니다. 쉘에서 할 수 있는 일

zsh -c -i 'echo $PS1'

(작은따옴표여야 하며, 큰따옴표는 실패합니다.)

나는 python(2.7)에서 다음과 같이 동일한 작업을 수행하려고 합니다 subprocess.

print subprocess.check_output(['-i','-c',r"'echo $PS1'"],executable="/bin/zsh")

이건 실패했어

subprocess.CalledProcessError: Command '['-i', '-c', "'echo $PS1'"]' returned non-zero exit status 127

나는 그것이 때문이라고 생각하지 않지만 $PS1오히려 echo-part를 매개 변수로 제공하는 방식 때문에 베어 문자열을 이런 식으로 에코하는 것도 실패하기 때문입니다.

왔다 갔다 하면서 다양한 조합을 시도하다 결국엔

prompt =  subprocess.check_output("""zsh -c -i 'echo $PS1'""",shell=True,executable="/bin/zsh")

이것은 작업을 수행하는 것처럼 보이지만 이것이 쉘을 시작하고 해당 쉘 내에서 다른 쉘을 호출하기 때문에 나에게는 잘못된 것 같습니다 -c -i 'echo $PS1'.

쉘 프롬프트를 얻는 올바른 방법은 무엇입니까?

답변1

print subprocess.check_output(['zsh','-i','-c','echo $PS1'])

다른 쉘에서 실행하는 경우 전체 문자열이 이후 단일 인수로 전달되도록 zsh주변 따옴표가 필요합니다 . 그들은 그래야만 한다echo $PS1-c하나의큰따옴표 안에 첫 번째 쉘이 확장되어 있기 때문에 따옴표가 있습니다 $PS1.

Python에서는 전체 명령이 단일 문자열이므로 다른 문자열처럼 인용됩니다. 두 번째 그룹을 추가하는 것은 'echo $PS1'(따옴표 포함) 입력하는 것과 같습니다 zsh. 쉘은 이름이 지정된 실행 파일을 찾지만 찾을 수 없습니다 'echo $PS1'.

답변2

올바른 방법은 다음과 같이 하위 프로세스를 호출하는 것입니다.

>>> prompt = subprocess.check_output("""echo $PS1""",shell=True,executable="/bin/zsh")

그런 다음 다음을 통해 결과를 확인 >>> prompt Enter 하거나 호출을 사용하여 결과를 직접 확인할 수 있습니다.

>>> subprocess.call("""echo $PS1""",shell=True,executable="/bin/zsh")

zsh따라서 명령 자체를 호출할 필요가 없습니다 .

Popen다음을 사용하여 대화형 통신을 수행할 수 있습니다.

>>> Popen(["/bin/zsh"], stdout=PIPE).communicate()[0]
SHELL_PROMPT% echo $PS1    
SHELL_PROMPT% exit  # exit to see the result of command   

이에 대한 자세한 내용은 다음을 참조하세요.하위 프로세스

shell=True위 링크 사용에 대한 경고도 참고하세요.

경고: 신뢰할 수 없는 소스의 삭제되지 않은 입력이 포함된 셸 명령을 실행하면 프로그램이 임의 명령 실행으로 이어질 수 있는 심각한 보안 결함인 셸 주입에 취약해집니다. 따라서 명령 문자열이 외부 입력에서 구성되는 경우 shell=True를 사용하는 것은 권장되지 않습니다.

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
shell=False does not suffer from this vulnerability; the above Note may be helpful in getting code using shell=False to work.

관련 정보