常见问题/解答(FAQ)

这些是我们从用户那里收到的最常见的问题或常见问题。它们不能代替阅读文档的其余部分,因此如果您的问题没有在这里得到回答,请确保您已经检查过了。

注解

大多数API示例和链接都是针对版本2和更高版本的;针对版本1的常见问题通常会标记为类似的。

我的 (cd /`` workon`/`` export``/etc)调用似乎不起作用!

虽然fabric可以用于许多类似shell脚本的任务,但有一个稍微不明确的捕获:每个 runsudo 呼叫(或) run/sudo v1)中的函数有自己独特的shell会话。为了让fabric在命令运行后可靠地确定其标准out/error和返回代码是什么,这是必需的。

不幸的是,这意味着像下面这样的代码并不像您想象的那样工作:

@task
def deploy(c):
    c.run("cd /path/to/application")
    c.run("./update.sh")

如果那是一个shell脚本,那么第二个 run 调用的当前工作目录为 /path/to/application/ --但是,由于这两个命令都在各自的不同会话中通过ssh运行,因此它实际上尝试执行 $HOME/update.sh 相反(因为远程主目录是默认的工作目录)。

一个简单的解决方法是使用shell逻辑操作,例如 && ,将多个表达式链接在一起(如果左侧执行时没有错误),如下所示:

def deploy(c):
    c.run("cd /path/to/application && ./update.sh")

注解

您也可以使用绝对路径,跳过目录更改:

def deploy(c):
    c.run("/path/to/application/update.sh")

但是,这要求所讨论的命令对当前工作目录不做任何假设!

为什么我有时会看到 err: stdin: is not a tty 是吗?

Invoke's FAQ 为此,即使对于不基于invoke的结构v1,答案也是一样的。

为什么我不能在后台运行程序 & ?它使 Fabric 挂起。

因为每次调用 runsudo (see also )时,后台进程可能会阻止调用shell退出,直到进程停止运行,这反过来又会阻止结构继续执行自己的执行。

修复此问题的关键是确保进程的标准管道都与调用shell断开,调用shell可以通过多种方式完成(按稳健性顺序列出):

  • 如果手头的程序存在守护程序,请使用预先存在的守护程序技术——例如,调用init脚本而不是直接调用服务器二进制文件。

    • 或利用流程管理器,如 supervisordupstartsystemd -这些工具允许您定义“运行”某个后台进程的含义,然后发出诸如start/stop/restart/status命令之类的init脚本。与经典的init脚本相比,它们也提供了许多优势。

  • 使用 tmuxscreendtach 为了使进程与正在运行的shell完全分离,这些工具的好处是允许您在以后需要时重新附加到进程(尽管它们比 supervisord 像工具一样。

  • 在下运行程序 nohup 或者类似的“在shell中”工具——请注意,对于大多数用户来说,这种方法的成功率是有限的。

有时我被错误地要求输入 passphrase 而不是 password 。

由于在我们的ssh层中有一个类似的错误,目前Fabric不可能总是准确地检测所需的身份验证类型。我们必须尝试猜测我们是被要求使用私钥密码还是远程服务器密码,在某些情况下,我们的猜测是错误的。

最常见的这种情况是,本地用户您似乎有一个ssh keychain代理正在运行,但是远程服务器无法使用您的ssh密钥,例如,您还没有将公钥传输过来,或者使用的用户名不正确。在这种情况下,fabric会提示您“请输入私钥的密码短语”,但您输入的文本实际上正被发送到远程端的密码验证。

我们希望在将来的版本中通过对前面提到的ssh库的贡献来解决这个问题。