이 질문의 목적 상, "csh"는 tcsh를 의미합니다.csh에 대한 문자열 인용하기
저는 csh 프로그래밍을 피하기위한 표준 조언을 알고 있습니다. 그러나 때로는 기존 csh 코드와 상호 작용할 필요가 있으며, csh에 문자열을 인용해야 할 수도 있습니다. 다시 말해, 문제는 csh 구문에서 임의의 바이트 문자열을 나타내는 방법입니다.
다음 csh_escape_arg 기능이 올바 릅니까? 즉, 테스트의 문자열 목록에 추가 된 문자열이 있으면 해당 테스트가 실패하게됩니다. 그러한 문자열이 있으면 어떻게 모든 문자열이 테스트를 통과하도록 함수를 수정할 수 있습니까?
import string
import subprocess
import unittest
# Safe unquoted
_safechars = frozenset(string.ascii_letters + string.digits + '@%_-+:,./')
def csh_escape_arg(str_):
"""Return a representation of str_ in csh.
Based on the standard library's pipes.quote
"""
for c in str_:
if c not in _safechars:
break
else:
if not str_:
return "''"
return str_
str_ = str_.replace("\\", "\\\\")
str_ = str_.replace("\n", "\\\n")
str_ = str_.replace("!", "\\!")
# use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b'
return "'" + str_.replace("'", "'\"'\"'") + "'"
def csh_escape(args):
return " ".join(csh_escape_arg(arg) for arg in args)
def get_cmd_stdout(args, **kwargs):
child = subprocess.Popen(args, stdout=subprocess.PIPE, **kwargs)
stdout, stderr = child.communicate()
rc = child.returncode
if rc != 0:
raise Exception("Command failed with return code %d: %s:\n%s" % (rc, args, stderr))
else:
return stdout
class TestCsh(unittest.TestCase):
def test_hard_cases(self):
for angry_string in [
"\\!\n\"'`",
"\\\\!\n\"'`",
"=0",
]:
out = get_cmd_stdout(["tcsh", "-c", csh_escape(["echo", "-n", angry_string])])
self.assertEqual(out, angry_string)
unittest.main()
Mark Armstrong이 지적한 '='문제를 수정하는 코드를 편집했습니다. –