我四处看了看,但什么也找不到。
基本上我想知道是否可以将getpass.getpass()
与 argparse 一起使用。
目前我有以下解决方法,我只是想知道是否有更好的方法:
import argparse
import getpass
parser = argparse.ArgumentParser(description="Some description")
parser.add_argument('-p', metavar="password", default="foobarblah123", help="password for user (default to prompt user)")
...
parsed_args = parser.parse_args()
args = vars(parsed_args)
user_pass = args['p']
if user_pass == "foobarblah123":
user_pass = getpass.getpass()
我很确定这不是处理此问题的最佳方法,但是,需要为密码设置命令行选项......最佳实践与否。
谢谢。
我可能已经找到了更好的方法。如何使用这样的自定义操作:
import argparse
import getpass
class PasswordPromptAction(argparse.Action):
def __init__(self,
option_strings,
dest=None,
nargs=0,
default=None,
required=False,
type=None,
metavar=None,
help=None):
super(PasswordPromptAction, self).__init__(
option_strings=option_strings,
dest=dest,
nargs=nargs,
default=default,
required=required,
metavar=metavar,
type=type,
help=help)
def __call__(self, parser, args, values, option_string=None):
password = getpass.getpass()
setattr(args, self.dest, password)
parser.add_argument('-u', dest='user', type=str, required=True)
parser.add_argument('-p', dest='password', action=PasswordPromptAction, type=str, required=True)
args = parser.parse_args()
环顾四周,没有找到足够的解决方案。 这是我想到的。
from argparse import ArgumentParser
from getpass import getpass
def main():
parser = ArgumentParser(description="arg parser hidden password input.")
parser.add_argument('-sp', '--secure_password', action='store_true', dest='password',
help='hidden password prompt')
args=parser.parse_args()
if args.password:
password = getpass()
print(password)
if __name__ == "__main__":
main()
显然,您会想要删除print(password)
,这只是为了验证其是否有效而添加的。
以下是我想出的提示输入非常小的密码(Python 3 代码):
import argparse
import getpass
class Password:
DEFAULT = 'Prompt if not specified'
def __init__(self, value):
if value == self.DEFAULT:
value = getpass.getpass('LDAP Password: ')
self.value = value
def __str__(self):
return self.value
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-u', '--username', help='Specify username',
default=getpass.getuser())
parser.add_argument('-p', '--password', type=Password, help='Specify password',
default=Password.DEFAULT)
args = parser.parse_args()
print(args.username, args.password)
使用示例:
$ python ~/Desktop/example.py -h
usage: example.py [-h] [-u USERNAME] [-p PASSWORD]
optional arguments:
-h, --help show this help message and exit
-u USERNAME, --username USERNAME
Specify username (default: gavinr)
-p PASSWORD, --password PASSWORD
Specify password (default: Prompt if not specified)
$ python ~/Desktop/example.py -p foo
gavinr foo
$ python ~/Desktop/example.py
LDAP Password:
gavinr foo
根据Rares Musina的回答,我注意到一个缺点:在命令行上提交密码时,提示符不断出现。当通过提示符提供密码时,argparse 会将命令行上已经给出的密码视为另一个参数(很可能不存在)。
在理想情况下,这是预期行为:
- 命令行
- 上未给出任何值时的密码提示
- 在命令行上给出值时没有提示
这两种情况都应被接受。理想情况下,第二种情况应发出安全警告。
将nargs
设置为 '?'
时,它需要零个或一个参数。这使得它可以选择通过命令行提供密码。
因此,将"add_argument"更改为:
arg_parser.add_argument("-p", "--password", type=str, action=PasswordPromptAction, nargs='?')
应编辑PasswordPromptAction
以加以区分。'values' 参数包含在命令行上给出的值(如果给定了一个):
class PasswordPromptAction(argparse.Action):
def __call__(self, parser, args, values, option_string=None):
# If no value is given on the commandline prompt for password.
if values:
# Ideally a security warning could be generated here.
setattr(args, self.dest, values)
else:
setattr(args, self.dest, getpass.getpass())
现在支持以下用法:
python program.py -p
python program.py -p p@ssw0rd
如果未在命令中指定密码,这将使用 getpass() 提示。很好,因为它支持自动脚本和手动使用隐藏密码。
import argparse
from getpass import getpass
parser = argparse.ArgumentParser(description="specify or prompt for a hidden password.")
parser.add_argument('-p', '--password', required=False, type=str)
args = parser.parse_args()
if not args.password:
args.password = getpass()
这个解决方案,因为用户可以同时传递:
$> python program.py login -u user1 -p pass1
或仅一个:
$> python program.py login -u user1
或任何:
$> python program.py 登录
如果参数未传递用户或密码,则以交互方式请求。
import argparse
import getpass
def parse_args():
parser = argparse.ArgumentParser(description="command line client")
subparser = parser.add_subparsers(dest='command', metavar='command')
subparser.required = True
parser.set_defaults(funct=argparser_handler)
# Login
sub_parser = subparser.add_parser("login", help="Login with email and password")
sub_parser.add_argument('-u', dest='user', help='user. If this argument is not passed it will be requested.')
sub_parser.add_argument('-p', dest='password', help='password. If this argument is not passed it will be requested.')
args = parser.parse_args()
args.funct(args)
def argparser_handler(args):
if (args.command == 'login'):
login(args.user, args.password)
def login(user, password):
if not user:
user = input("User:")
if not password:
password = getpass.getpass()
print("user:", user)
print("password:", password)
def main():
pass
if __name__ == '__main__':
parse_args()
main()