在fabric执行命令中使用密码

2 投票
2 回答
662 浏览
提问于 2025-04-17 20:56

我想用fabric从我们的一个服务器上获取日志。这需要从另一个Python程序中执行。问题是我们没有SSH密钥,只有密码。你能帮我提供连接服务器的密码吗?

代码:

from fabric.api import *
from fabric.tasks import execute

def get_logs():
    get('/var/logs/custom', ".")

if __name__ == '__main__':
    execute(get_logs, hosts=["username@hostname",])

错误信息

**[username@hostname] Executing task 'get_logs'
Traceback (most recent call last):
  File "D:\Python\ws\fabric\Fabric_test\example.py", line 8, in <module>
    execute(get_logs, hosts=["username@hostname",])
  File "D:\Python\ws\fabric\lib\site-packages\fabric\tasks.py", line 368, in execute
    multiprocessing
  File "D:\Python\ws\fabric\lib\site-packages\fabric\tasks.py", line 264, in _execute
    return task.run(*args, **kwargs)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\tasks.py", line 171, in run
    return self.wrapped(*args, **kwargs)
  File "D:\Python\ws\fabric\Fabric_test\example.py", line 5, in get_logs
    get('/var/logs/custom/', ".")
  File "D:\Python\ws\fabric\lib\site-packages\fabric\network.py", line 639, in host_prompting_wrapper
    return func(*args, **kwargs)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\operations.py", line 528, in get
    ftp = SFTP(env.host_string)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\sftp.py", line 30, in __init__
    self.ftp = connections[host_string].open_sftp()
  File "D:\Python\ws\fabric\lib\site-packages\fabric\network.py", line 151, in __getitem__
    self.connect(key)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\network.py", line 143, in connect
    self[key] = connect(user, host, port, cache=self)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\network.py", line 523, in connect
    password = prompt_for_password(text)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\network.py", line 604, in prompt_for_password
    new_password = _password_prompt(password_prompt, stream)
  File "D:\Python\ws\fabric\lib\site-packages\fabric\network.py", line 576, in _password_prompt
    return getpass.getpass(prompt.encode('ascii', 'ignore'), stream)
TypeError: pydev_getpass() takes at most 1 argument (2 given)

**

2 个回答

1

看起来你是在用IDE(比如PyDev)运行这个脚本,而这个IDE把getpass.getpass()这个函数替换成了它自己的一个函数pydev_getpass()。这个新函数的参数不一样,它不接受第二个参数stream

如果你从命令行运行这个脚本,就不会出现这个错误了。

0

最后通过作为操作系统的命令来解决了这个问题。下面是完整的代码片段。

import os, shutil
from subprocess import check_output

from fabric.api import get

def get_logs(source_dir):
    get('/var/logs/custom', source_dir)

def fetch_logs(hostname, username, password):
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))
    current_file_name = os.path.abspath(__file__).replace(".pyc", ".py")
    local_path = os.path.join(BASE_DIR, 'data', hostname)
    try:
        shutil.rmtree(local_path)
    except:
        pass
    exe = os.path.join(BASE_DIR, "..", "Scripts", "fab.exe")
    input_cmd = exe + " -H " + hostname + " -u " + username + " -p " + password + " -f " + current_file_name + " get_logs:source_dir:" + local_path
    try:
        check_output(input_cmd, shell=True)
    except Exception as e:
        print e
        return False
    shutil.move(os.path.join(BASE_DIR, 'download'), local_path)
    return True

撰写回答