我环顾四周,但找不到任何东西。
基本上我想知道是否可以将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()
我很确定这不是处理此问题的最佳方法,但是,需要为密码设置命令行选项...最佳做法与否。
感谢。
答案 0 :(得分:13)
我想我可能找到了一个更好的方法来做到这一点。如何使用这样的自定义Action:
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()
答案 1 :(得分:6)
环顾四周,找不到足够的解决方案。这就是我想出来的。
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)
,这只是为了验证它是否有效而添加。
答案 2 :(得分:5)
以下是我提出的用于提示密码非常小(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
答案 3 :(得分:1)
基于Rares Musina的答案,我注意到一个缺点: 在命令行上提交密码后,提示将不断出现。然后在通过提示提供密码时,argparse会将命令行上已经提供的密码视为另一个参数(很可能不存在)。
在理想情况下,这是预期的行为:
两种情况都应接受。理想情况下,第二种情况应该发出安全警告。
将nargs
设置为'?'
时,它期望参数为零或一个。这使得它可以选择通过命令行提供密码。
因此将“ add_argument”更改为:
arg_parser.add_argument("-p", "--password", type=str, action=PasswordPromptAction, nargs='?')
PasswordPromptAction
应该进行区分。 “值”参数包含在命令行上给出的值(如果给出了值):
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
答案 4 :(得分:1)
如果未在命令中指定密码,则将使用getpass()提示。不错,因为它支持自动脚本和带有隐藏密码的手动使用。
import argparse
from getpass import getpass
parser = 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()
答案 5 :(得分:0)
我喜欢这种解决方案,因为用户可以同时通过两种方式:
$> python program.py登录 -u user1 -p pass1
或仅一个:
$> python program.py登录 -u user1
或任何
$> python program.py登录
如果未通过param传递用户或密码,则以交互方式请求。
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()