如何使用fabric在任意主机,多平台,Linux和Windows上创建文件夹/目录?

时间:2014-01-16 06:13:13

标签: python fabric

我正在使用python结构编写多服务器维护模块,我遇到了一个问题,我需要在随机服务器上创建一个文件夹,这可以是Linux服务器或Windows,因此这些机器上的命令是不同的。

然而,这可以在本地机器上使用python轻松完成,比如

if not os.path.exists(MyDir):
        os.makedirs(MyDir)

但如何在任意平台上使用面料做一些事情?

我有这样的想法,

class FabricSupport:
    def __init__(self):
        pass

    def run(self, host = 'localhost', port = '22', command = None):  
        if host != 'localhost':
            env.host_string = "%s:%s" % (host, port)
            with hide('output','running','warnings'):
                return run(command, shell=False)
        else:
            with hide('running'):
                return local(command)

所以我希望这个类可以有一个创建文件夹的功能。 然后我发现我将遇到一个问题,让它在不同的平台上运行。

    def createdir(self, targetdir, host = 'localhost', port = '22'):
        if host != 'localhost':
            env.host_string = "%s:%s" % (host, port)
            with hide('output','running','warnings'):
                if not exists(targetdir):
                    return run('mkdir %s' % targetdir, shell=False)
        else:
            with hide('running'):
                return local('mkdir %s' % targetdir)

我发现fabric.contrib.files.exists可以检查文件夹是否存在,但创建一个文件夹怎么样? 如果'mkdir'不起作用怎么办?

更新解决方案:

感谢user865368,我在这里得到了一个完整的解决方案。这可能看起来很愚蠢,但我看不出更好的一个。

class FabricRunReturnSimulator:
    def __init__(self):
        self.info = None
    def __str__(self):
        return "%s" % (self.info)
    pass

def createdir(self, targetdir, host = 'localhost', port = '22'):
    """
    Create a input target dir on local or remote.
    targetdir can be a single string or a list (the sequence of the elements must follow the intended path)

    return code 2: makedir runs into trouble, maybe permission problem
    return code 3: target directory exists
    return code 0: runs normal
    """

    if host != 'localhost':
        env.host_string = "%s:%s" % (host, port)
        with hide('output','running','warnings'), settings(warn_only=True, shell=False):
            if not isinstance(targetdir, list):
                return run('''python -c "import os\nif not os.path.exists('%s'):\ntry:\n  os.makedirs('%s')\nexcept:  exit(2)" ''' % (targetdir, targetdir), capture=True)
            else:
                targetdirpass = repr(targetdir)
                return run('''python -c "import os\ntd = os.path.join(*%s)\nif not os.path.exists(td):\ntry:\n  os.makedirs(td)\nexcept:  exit(2)" ''' % (targetdirpass), capture=True)
    else:
        simulatereturn = FabricRunReturnSimulator()
        if not isinstance(targetdir, list):
            if not os.path.exists(targetdir):
                try:
                    os.makedirs('%s' % targetdir)
                    simulatereturn.return_code = 0
                    simulatereturn.failed = False
                    simulatereturn.succeeded = True
                    simulatereturn.info = ''.join((targetdir , " Folder Created."))
                except:
                    simulatereturn.return_code = 2
                    simulatereturn.failed = True
                    simulatereturn.succeeded = False
                    simulatereturn.info = ''.join(("Unable to create folder ",targetdir))
            else:
                simulatereturn.return_code = 3
                simulatereturn.failed = True
                simulatereturn.succeeded = False
                simulatereturn.info = ''.join((targetdir , " already exists."))
        else:
            td = os.path.join(*targetdir)
            if not os.path.exists(td):
                try:
                    os.makedirs('%s' % td)
                    simulatereturn.return_code = 0
                    simulatereturn.failed = False
                    simulatereturn.succeeded = True
                    simulatereturn.info = ''.join((td , " Folder Created."))
                except:
                    simulatereturn.return_code = 2
                    simulatereturn.failed = True
                    simulatereturn.succeeded = False
                    simulatereturn.info = ''.join(("Unable to create folder " , td))
            else:
                simulatereturn.return_code = 3
                simulatereturn.failed = True
                simulatereturn.succeeded = False
                simulatereturn.info = ''.join((td , " already exists."))
        return simulatereturn

1 个答案:

答案 0 :(得分:1)

如果你想留在Python中,你可以继续执行

run('''python -c "import os;os.mkdir('some dir')" ''')

这需要你知道每个系统上可执行的python的路径,它可以改变。

否则你可以做类似的事情:

  1. 连接主机
  2. 使用detect_os
  3. 查找操作系统
  4. 分支取决于操作系统
  5. 使用'mkdir'或'md'
  6. 无论如何,你必须分支/检测os,没有完全多平台的方法。