os.system ()을 사용할 때 종종 명령에 매개 변수로 전달 된 파일 이름 및 기타 인수를 이스케이프해야합니다. 어떻게 할 수 있습니까? 여러 운영 체제 / 쉘에서 작동하지만 특히 bash에서는 작동하는 것이 좋습니다.
저는 현재 다음을 수행하고 있지만이를위한 라이브러리 함수 또는 적어도 더 우아하고 / 튼튼하고 / 효율적인 옵션이 있어야합니다.
def sh_escape(s):
return s.replace("(","\\(").replace(")","\\)").replace(" ","\\ ")
os.system("cat %s | grep something | sort > %s"
% (sh_escape(in_filename),
sh_escape(out_filename)))
편집 : 따옴표 사용에 대한 간단한 대답을 받아 들였습니다. 왜 그렇게 생각하지 않았는지 모르겠습니다. 나는 Windows에서 왔기 때문에 ‘와 “가 약간 다르게 작동하는 것 같습니다.
보안과 관련하여 우려 사항을 이해하지만이 경우 os.system ()이 제공하는 빠르고 쉬운 솔루션에 관심이 있으며 문자열의 소스는 사용자가 생성하지 않았거나 최소한 사용자가 입력 한 것입니다. 신뢰할 수있는 사용자 (나).
답변
이것이 내가 사용하는 것입니다.
def shellquote(s):
return "'" + s.replace("'", "'\\''") + "'"
쉘은 항상 따옴표로 묶인 파일 이름을 받아들이고 문제의 프로그램에 전달하기 전에 주변 따옴표를 제거합니다. 특히 이것은 공백이나 기타 불쾌한 쉘 메타 문자를 포함하는 파일 이름의 문제를 방지합니다.
업데이트 : Python 3.3 이상을 사용하는 경우 직접 롤링하는 대신 shlex.quote 를 사용 하십시오.
답변
답변
.NET을 사용하는 특별한 이유가있을 수 있습니다 os.system()
. 그러나 그렇지 않다면 아마도 모듈 을 사용해야 할 것입니다.subprocess
. 파이프를 직접 지정하고 셸 사용을 피할 수 있습니다.
Replacing shell pipe line ------------------------- output=`dmesg | grep hda` ==> p1 = Popen(["dmesg"], stdout=PIPE) p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) output = p2.communicate()[0]
답변
어쩌면 subprocess.list2cmdline
더 나은 샷일까요?
답변
pipes.quote는 실제로 Python 2.5 및 Python 3.1에서 깨졌고 사용하기에 안전하지 않습니다. 길이가 0 인 인수를 처리하지 않습니다.
>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1 arg3
Python issue 7476을 참조하십시오 . Python 2.6 및 3.2 이상에서 수정되었습니다.
답변
주의 : 이것은 Python 2.7.x에 대한 답변입니다.
에 따르면 소스 , pipes.quote()
“할 수있는 방법이다 안정적에 대해 하나의 인수로 문자열 인용 / 빈 / SH는 “. (단, 버전 2.7부터 사용되지 않고 마침내 Python 3.3에서 shlex.quote()
함수 로 공개적으로 노출되었습니다 .)
에 다른 한편으로 , subprocess.list2cmdline()
“할 수있는 방법 은 AS와 동일한 규칙을 사용하여 명령 행 문자열로 인수의 순서를 번역 MS C 런타임 “.
여기에 명령 줄에 대한 문자열을 인용하는 플랫폼 독립적 인 방법이 있습니다.
import sys
mswindows = (sys.platform == "win32")
if mswindows:
from subprocess import list2cmdline
quote_args = list2cmdline
else:
# POSIX
from pipes import quote
def quote_args(seq):
return ' '.join(quote(arg) for arg in seq)
용법:
# Quote a single argument
print quote_args(['my argument'])
# Quote multiple arguments
my_args = ['This', 'is', 'my arguments']
print quote_args(my_args)
답변
나는 os.system이 사용자를 위해 구성된 명령 쉘을 호출한다고 믿기 때문에 플랫폼 독립적 인 방식으로 할 수 있다고 생각하지 않습니다. 내 명령 셸은 bash, emacs, ruby 또는 quake3의 모든 것이 될 수 있습니다. 이 프로그램 중 일부는 당신이 그들에게 전달하는 주장의 종류를 기대하지 않으며 그들이 그렇게하더라도 그들이 같은 방식으로 탈출한다는 보장이 없습니다.