Linux 시스템에 Python 버전이 있습니다 - 2.7.5 - redhat 7.3
sed를 사용하여 파일의 문자열을 바꾸는 간단한 스크립트를 작성했습니다.
more test.py
#!/usr/bin/env python
import subprocess
subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml")
하지만 우리는 얻었다
Traceback (most recent call last):
File "./test.py", line 5, in <module>
subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml")
File "/usr/lib64/python2.7/subprocess.py", line 524, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
파이썬 스크립트에 어떤 문제가 있나요?
more file.xml
2.6.0.3-8
답변1
파이썬에서는:
그것을 사용할 때
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
또는subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
args
이는 모든 호출에 필요하며 프로그램 매개변수의 문자열 또는 시퀀스여야 합니다.일반적으로 다양한 매개변수를 제공하는 것이 선호됩니다., 모듈이 필수 매개변수 이스케이프 및 인용(예: 파일 이름에 공백 허용)을 처리할 수 있도록 허용하기 때문입니다. 이는 단일 문자열이 전달되는 경우shell
true여야 하며True
(아래 참조), 그렇지 않으면 문자열은 인수를 지정하지 않고 실행할 프로그램의 이름만 지정해야 합니다.
...
그렇다면 지정된 명령shell
이True
셸을 통해 실행됩니다. Python이 대부분의 시스템 셸에서 제공하는 제어 흐름을 향상하기 위해 주로 Python을 사용하고 있고 여전히 셸 파이프, 파일 이름 와일드카드, 환경 변수 확장 및~
사용자 홈 디렉터리 확장과 같은 다른 셸 기능에 쉽게 액세스하려는 경우 다음과 같이 할 수 있습니다. 유용한. .
따라서 다음과 같이 지정하면 방법이 작동합니다.
subprocess.call("sed s'/2\.6/2.6.4/g' /tmp/file.xml", shell=True)
하지만...
경고하다:
shell=True
사용시 안전상의 위험이 있을 수 있습니다.
신뢰할 수 없는 소스의 정제되지 않은 입력이 포함된 셸 명령을 실행하면 프로그램이 공격에 취약해집니다.쉘 주입, 임의의 명령 실행으로 이어질 수 있는 심각한 보안 취약점입니다. 이러한shell=True
이유로매우 낙담함 명령 문자열이 외부 입력으로 구성된 경우.
shell=True
를 사용하면pipes.quote()
셸 명령을 구성하는 데 사용되는 문자열의 공백과 셸 메타 문자를 올바르게 이스케이프하는 데 사용할 수 있습니다.
결론: 명령을 args
단일 문자열( shell=True
set)로 전달하는 경우 최소한 이스케이프/인용해야 합니다. 그러나 위에서 언급한 것처럼 다양한 매개변수를 제공하는 것이 좋습니다.
import subprocess
subprocess.call(['sed', 's/2\.6/2.6.4/g', '/tmp/file.xml'])