使用子进程调用时,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=True
到 Popen
。这意味着 ssh-keygen
的 argv
将是
['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 应该会阻止它正常运行。
我想知道在脚本中调用 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=True
到 Popen
。这意味着 ssh-keygen
的 argv
将是
['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 应该会阻止它正常运行。