【问题标题】:How to call preserve quotes when passing arguments? [duplicate]传递参数时如何调用保留引号? [复制]
【发布时间】:2019-11-22 20:58:09
【问题描述】:

我有一段看起来像这样的代码。真正的代码当然要长得多。我已将其缩短以将其浓缩为这个想法。

#!/usr/bin/python

from sys import argv

class Base():
    def whoami(self):
        print(self.__class__.__name__)

    def foo(self, a, b):
        print(a+b)

class A(Base):
    def bar(self, a):
        print(a)

class B(Base):
    def fizz(self, a, b):
        print(a+b)

def main():
    eval(argv[1] + '().' + argv[2] + '(' + ', '.join(argv[3:]) + ')')

if __name__ == "__main__":
    main()

预期输出:

$ ./myScript.py A whoami
A
$ ./myScript.py B fizz 5 7
12
$ ./myScript.py B fizz '5' '7'
57

但最后一行的实际输出是:

$ ./myScript.py B fizz '5' '7'
12

引号没有通过。我的目标是能够从命令行轻松调用各种类方法进行调试。我不知道我的做法是不是一开始就错了。

是的,我知道eval 存在安全风险。我打算在代码投入生产时将其删除。

【问题讨论】:

  • 引号永远不会被保留,因为这些是shell如何解释参数的“指令”。它通常用于在参数中添加空格,例如command 'foo bar' qux,而不是command foo bar qux
  • 可能是this answer 会有所帮助。
  • 您可以在参数中添加引号,例如myscripty.py B fizz '"5"' '"7"'
  • 像这样使用 eval 会让安全工程师心脏病发作,让渗透测试员在现场度过一天
  • @WillemVanOnsem 这是一个可行的解决方案。您可以将其发布为答案。

标签: python bash command-line-interface command-line-arguments


【解决方案1】:

引号没有通过。我的目标是能够从命令行轻松调用各种类方法进行调试。

引号不是您使用的参数的一部分。引号由 shell 解释。通常使用引号给参数添加空格。

例如:

command foo bar

会将两个参数(foobar)传递给command,但是如果要添加空格,可以使用:

command 'foo bar'

现在,shell 会将其解释为带有空格的单个参数。

但是,您可以在参数中添加引号,例如:

command '"foo"' '"bar"'

或:

command "'foo'" "'bar'"

将带引号的值(第一个示例中的双引号 " 和第二个示例中的单引号 ')传递给命令。您也可以转义部分参数,例如command "\"Thank you\", she said.",从而在同一参数中使用双引号和单引号。

话虽如此,请不要使用eval(..) 来评估字符串。 eval(..) 具有严重的安全风险,请参阅Security of Python's eval() on untrusted strings? 了解更多信息。您可以使用 ast.literal_eval [python-doc] 来评估文字。此外,您可以使用字典等将调用路由到正确的函数。

【讨论】:

  • 不错的答案。我会等几天接受它,以防出现更好的情况。我已经投票了。
  • 怎么会有更好的办法呢?这是事实,就 shell 如何将命令字符串解析为参数向量而言。
猜你喜欢
  • 2010-12-12
  • 1970-01-01
  • 2013-01-05
  • 2010-12-31
  • 1970-01-01
  • 2015-10-05
  • 2011-10-22
  • 2012-06-05
相关资源
最近更新 更多