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

ssh-keygen raise password too short error when called with subprocess

我想知道在脚本中调用 ssh-keygen 时是否需要使用 subprocess 或不使用 来做一些不同的事情。 我 运行 正在 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-like 环境中使用 shell 类似 bash 或类似的(如变量 bashCommand 暗示). Windows.

的工作方式大不相同

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

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

shell 扩展了字符串,并去除了所有引号。当你拆分你的命令时,参数被传递 as-is,因为你没有指定 shell=TruePopen。这意味着 ssh-keygenargv 将是

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

希望您能看出其中的区别。 -N 的参数不再为空。是一个two-character字符串"",明显少于五个字符

您不需要字符串 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-like 案例的解决方案(但它会起作用)。

如评论中所述,您的代码在健壮性、可维护性和美观性方面存在其他问题。但是,none 应该会阻止它正常运行。