如何让 argparse 为具有两个名称的 python 脚本显示一个帮助页面?
How do I get argparse to show one help page for a python script with two names?
我当前的工作 python 脚本使用 getopts,因为它是对使用 Getopt::Long 的 perl 脚本的重写。我想迁移到 argparse,但失败了,因为这些选项不太适合 argparse 的工作方式。
然后我有了一个好主意 [?],如果我的脚本有 2 个名称怎么办,例如:foo-ssh 和 foo-rsync
并将 foo-rsync 符号链接到 foo-ssh(超过 90% 的脚本是 foo-ssh,rsync 选项是一个附加组件,不适合作为选项),然后将代码放在脚本仅处理其 运行 下的特定名称的选项。
我知道子解析器,但它看起来并不完全像我正在寻找的那样,并且产生了比我开始时更加丑陋和混乱的帮助输出。
如果我尝试尽可能接近 argparse 的 getopts 方式,我会得到这个:
usage: foo-ssh [-h] [--version] [--debug] [--forward-agent HOST:PORT]
[--ipv4] [--knock HOST:PORT]
[--libvirt-vnc HOST:PORT | --rsync]
[USER@]HOST
哪个是错的,哪个是对的,就是不对。
来自 perl 脚本帮助页面:
Usage: foo-ssh <options> [USER@]HOST
foo-ssh <options> --knock HOST:PORT [USER@]HOST
foo-ssh <options> --libvirt-vnc HOST:PORT [USER@]HOST
foo-ssh <options> --rsync -- <rsync options> [USER@]HOST:/path/file.name /tmp
我想要什么:
usage: foo-ssh [-h] [--version] [--debug] [--forward-agent HOST:PORT]
[--ipv4] [--knock HOST:PORT]
[--libvirt-vnc HOST:PORT]
[USER@]HOST
foo-rsync [OPTION...] [USER@]HOST:SRC... [DEST]
foo-rsync [OPTION...] SRC... [USER@]HOST:DEST
首先,我在这里是在打死马吗?如果我用相同数量或更多的代码来替换已经工作的代码,那么整个练习就毫无意义。
其次,这可能吗?我正在寻找什么来实现它?
脚注:未包含 Perl 代码示例,因为它写得像河马用自己的便便标记它的领地(即:到处都是),这是重写的原因之一。
检查 sys.argv[0]
的值以查看调用脚本的名称,然后构建适当的 ArgumentParser
作为响应。
if sys.argv[0].endswith("foo-ssh"):
parser = ArgumentParser(epilog="For rsync, run foo-rsync")
parser.add_argument(...)
...
elif sys.argv[0].endswith("foo-rsync"):
parser = ArgumentParser(epilog="For ssh, run foo-ssh")
parser.add_argument(...)
else:
sys.exit("Must be invoked as foo-ssh or foo-rsync, not {}".format(sys.argv[0]))
args = parser.parse_args()
(如果 epilog
会下降 "below the fold",请将对其他脚本的引用放在 description
中。)
我当前的工作 python 脚本使用 getopts,因为它是对使用 Getopt::Long 的 perl 脚本的重写。我想迁移到 argparse,但失败了,因为这些选项不太适合 argparse 的工作方式。
然后我有了一个好主意 [?],如果我的脚本有 2 个名称怎么办,例如:foo-ssh 和 foo-rsync
并将 foo-rsync 符号链接到 foo-ssh(超过 90% 的脚本是 foo-ssh,rsync 选项是一个附加组件,不适合作为选项),然后将代码放在脚本仅处理其 运行 下的特定名称的选项。
我知道子解析器,但它看起来并不完全像我正在寻找的那样,并且产生了比我开始时更加丑陋和混乱的帮助输出。
如果我尝试尽可能接近 argparse 的 getopts 方式,我会得到这个:
usage: foo-ssh [-h] [--version] [--debug] [--forward-agent HOST:PORT]
[--ipv4] [--knock HOST:PORT]
[--libvirt-vnc HOST:PORT | --rsync]
[USER@]HOST
哪个是错的,哪个是对的,就是不对。
来自 perl 脚本帮助页面:
Usage: foo-ssh <options> [USER@]HOST
foo-ssh <options> --knock HOST:PORT [USER@]HOST
foo-ssh <options> --libvirt-vnc HOST:PORT [USER@]HOST
foo-ssh <options> --rsync -- <rsync options> [USER@]HOST:/path/file.name /tmp
我想要什么:
usage: foo-ssh [-h] [--version] [--debug] [--forward-agent HOST:PORT]
[--ipv4] [--knock HOST:PORT]
[--libvirt-vnc HOST:PORT]
[USER@]HOST
foo-rsync [OPTION...] [USER@]HOST:SRC... [DEST]
foo-rsync [OPTION...] SRC... [USER@]HOST:DEST
首先,我在这里是在打死马吗?如果我用相同数量或更多的代码来替换已经工作的代码,那么整个练习就毫无意义。
其次,这可能吗?我正在寻找什么来实现它?
脚注:未包含 Perl 代码示例,因为它写得像河马用自己的便便标记它的领地(即:到处都是),这是重写的原因之一。
检查 sys.argv[0]
的值以查看调用脚本的名称,然后构建适当的 ArgumentParser
作为响应。
if sys.argv[0].endswith("foo-ssh"):
parser = ArgumentParser(epilog="For rsync, run foo-rsync")
parser.add_argument(...)
...
elif sys.argv[0].endswith("foo-rsync"):
parser = ArgumentParser(epilog="For ssh, run foo-ssh")
parser.add_argument(...)
else:
sys.exit("Must be invoked as foo-ssh or foo-rsync, not {}".format(sys.argv[0]))
args = parser.parse_args()
(如果 epilog
会下降 "below the fold",请将对其他脚本的引用放在 description
中。)