python - 使用子进程调用时,ssh-keygen 会引发密码太短错误

标签 python subprocess ssh-keygen

我想知道当我在脚本中使用subprocess调用ssh-keygen时是否需要做一些不同的事情。 我正在Linux环境中运行。 这是我的代码:

    cfg_r = configparser.ConfigParser()
    cfg_r.read('ssh_config.cfg')
    p_mail=cfg_r.get('Company', 'mail')
    bashCo m mand="ssh-keygen -t rsa -f /home/pi/.ssh/id_rsa  - C \"{}\" -q -N \"\"".format(p_mail)
    print(bashCommand.split())
    proc = subprocess.Popen(bashCommand.split(),
            stdout=subprocess.PIPE,
            stderr=open('logfile_Get_conf.log', 'a'),
            preexec_fn=os.setpgrp
            )
    outpu.stdout.read().decode('utf-8')

我使用configparser来阅读除此之外的电子邮件,没有什么特别的。

bashCommand 应该是这样的:

ssh-keygen -t rsa -f /home/pi/.ssh/id_rsa -C "mail@gmail.com" -q -N ""

bashCommand.split() 也应该如此:

['ssh-keygen', '-t', 'rsa', '-f', '/home/pi/.ssh/id_rsa', '-C', '"mail@gmail.com"', '-q', '-N', '""']

非常奇怪的是,当我在 shell 中运行这个 bashCommand 时,没有出现任何问题:

ssh-keygen -t rsa -f /home/pi/.ssh/id_rsa -C "mail@gmail.com" -q -N ""

但是在我的日志文件中我仍然有这个错误:

Saving key "/home/pi/.ssh/id_rsa" failed: passphrase is too short (minimum five characters)

问题出在哪里?

最佳答案

我假设您正在类 Unix 环境中运行,并使用类似 bash 或类似的 shell(如变量 bashCommand 所暗示的那样)。 Windows 中的工作方式非常不同。

当您运行在 shell 中显示的命令时,作为 argv 传递给 ssh-keygen 的参数为(Python 语法):

['ssh-keygen', '-t', 'rsa', '-f', '/home/pi/.ssh/id_rsa', '-C', 'mail@gmail.com', '-q', '-N', '']

shell 展开字符串,并去掉所有引号。当您拆分命令时,参数将按原样传递,因为您没有为 Popen 指定 shell=True。这意味着 ssh-keygenargv 将是

['ssh-keygen', '-t', 'rsa', '-f', '/home/pi/.ssh/id_rsa', '-C', '"mail@gmail.com"', '-q', '-N', '""']

希望您能看到其中的差异。 -N 的参数不再为空。这是一个两个字符的字符串"",显然少于五个字符。

您不需要字符串bashCommand。使用列表要方便得多,然后直接将内容传递给 Popen:

bashCommand = ['ssh-keygen', '-t', 'rsa', '-f', '/home/pi/.ssh/id_rsa', '-C', p_mail, '-q', '-N', '']
proc = subprocess.Popen(bashCommand, ...)

请注意,这样,您不需要对命令行进行任何字符串插值、花哨的分割、引用、转义或其他修改。

我曾提到过 Windows 上的工作方式非常不同。这是因为在 Windows 上,shell=True 始终被设置,并且您对此无能为力。 Windows 不会像 Unix 那样将 argv 传递给程序。相反,程序负责解析自己的命令行字符串,因此必须使用引号。使用 shell=True 通常会受到反对,因此我不建议使用它作为类 Unix 情况的解决方案(但它会起作用)。

正如评论中提到的,您的代码中还存在鲁棒性、可维护性和美观性方面的其他问题。但是,它们都不应阻止其正常运行。

关于python - 使用子进程调用时,ssh-keygen 会引发密码太短错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57167936/

相关文章:

Python - 在 Windows 上运行一个带有提示 I/O 和 "proxy"的简单命令行程序

git - 我应该在我的 ssh 公钥中使用我的个人电子邮件吗?

node.js - 无法解析私钥 : Unsupported key format

python - 如何从特定显示器上的 python 绑定(bind)启动 VLC 实例?

python - 如何从 Pyspark 中的 spark 数据框创建边缘列表?

python - 如何使用 Sqlalchemy 根据计算出的 json 值选择 Postgresql 记录?

linux - `ssh-keygen -A` 到底是做什么的?

python - 有没有一种有效的方法可以只获得列表的 K 组合?

python - 从 Python 子进程返回值

python - 在Python中将密码发送到sftp子进程