Python,创建os.system调用时的最佳选择

时间:2014-09-08 23:54:42

标签: python macos

我希望使用mount_smbfs(OSX上的python)连接到SMB共享。我试图找到最有效的方法来做到这一点。以下是我的想法,但我不确定如何将可修改的名称正确放入命令行字符串。

def connect_creds(server,domain,username,password):
    dir = "/root/tmp"
    if not os.path.exists(dir): os.makedirs(dir)
    os.system("mount_smbfs //", domain, , ";", username, ":", password, "@", server, "/Share", " ", dir)

任何有关前进的最佳方式的建议都将受到赞赏。

2 个答案:

答案 0 :(得分:4)

您的代码实际上无法运作:

os.system("mount_smbfs //", domain, , ";", username, ":", password, "@", server, "/Share", " ", dir)

您使用一系列不同的参数调用os.system"mount_smbfs //",然后是domain,依此类推。但它只需要一个论点。

我认为你期望它像print一样工作 - 但即使这样做,print也会在每个元素之间留出空格,所以你最终会得到{{} 1}},这不会带来很多好处。

如果您想将它们连接在一起,可以使用USER : PASS @ SERVER运算符,或者更好的+来实现,如下所示:

str.format

但那仍然无法发挥作用,因为shell会将os.system("mount_smbfs //{};{}:{}@{}/Share {}".format( domain, username, password, server, dir) 误解为分隔两个语句的特殊字符。并且,如果在任何字符串中都有空格或其他特殊字符,则在没有引用的情况下也会失败。

如果你真的想和它斗争,所有这一切都是可以解决的,但没有充分的理由这样做。正如os.system的文档所说:

  

subprocess模块提供了更强大的工具来生成新流程并检索其结果;使用该模块比使用此功能更可取。

以下是;

的处理方式
subprocess

这使得shell完全脱离了它 - 这在某种程度上更有效率(不是它可能更重要),但也简单得多,因为你不必担心转义或引用特殊的shell字符。它也更强大;如果调用失败,而不是静默失败,它将引发异常。使用subprocess.check_call(['mount_smbfs', '//{};{}:{}@{}/Share'.format(domain, username, password, server), dir]) 还可以捕获stdout或stderr,或者执行各种其他操作,只需对代码进行少量更改。

答案 1 :(得分:2)

请勿使用os.system。使用标准库中的subprocess module

os.system的问题在于它将命令行传递给shell(例如bashcsh),这会带来许多安全风险以及shell的机会修改命令行,例如错误地检测特殊字符,shell变量,带引号的字符串,空格或转义。

使用subprocess,您可以指定外部程序接收的确切的单个命令行参数。*您可能会使用以下内容:

subprocess.call(("mount_smbfs", "//%s;%s:%s@%s/Share" % (domain, username, password,
    server), dir))

请注意,无需担心参数中可能出现的空格或特殊字符。

*这适用于MacOS和任何其他POSIX-y操作系统;它在Windows上非常可靠,但是在命令行的POSIX模型作为字符串数组和Windows / DOS模型作为单个字符串之间明确地映射是不可能的。