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.